P1113 杂务
一题多解
一开始建图来写,写错了,发现有递推关系,写了下就对了,后面把拓扑排序的写法调了出来
递推1:
分析:第u个杂物做之前和第1~k-1个杂物存在关系,我们只需要找到 要在第u个杂物做之前 找到存在关系的最大完成的杂物时间 就能推出公式,f[u]=a[u]+max(len[v]); v代表存在关系的杂物里的最大时间。
代码:
#include<iostream>
#include<cstring>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
int n,m;
vector<int> son[100010];
int len[100010];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
int x; cin>>x;
cin>>len[i];
int y;
int add=0;
while(cin>>y)
{
if(y==0)
break;
son[y].push_back(x);
add=max(len[y],add);
}
len[x]+=add;
}
int ans=0;
for(int i=1;i<=n;i++)
ans=max(ans,len[i]);
cout<<ans<<endl;
return 0;
}
拓扑排序
分析:也是找到入度为0的点加入队列,每次遍历到子节点更新子节点的时间,类似dp的方式,见下:
while(!q.empty())
{
int t=q.front();q.pop();
for(auto v:son[t])
{
if(--d[v]==0)
{
f[v]=max(f[v],f[t]+len[v]); //此处
q.push(v);
}
}
}
完整代码:
#include<iostream>
#include<cstring>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
int n,m;
vector<int> son[100010];
int d[100010];
int len[100010];
int f[100010];
void bfs()
{
queue<int> q;
for(int i=1;i<=n;i++)
if(d[i]==0)
{
f[i]=len[i];
q.push(i);
}
while(!q.empty())
{
int t=q.front();q.pop();
for(auto v:son[t])
{
if(--d[v]==0)
q.push(v);
f[v]=max(f[v],f[t]+len[v]);
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
int x; cin>>x;
cin>>len[i];
int y;
while(cin>>y)
{
if(y==0)
break;
son[y].push_back(x);
d[i]++;
}
}
bfs();
int ans=0;
for(int i=1;i<=n;i++)
ans=max(ans,f[i]);
cout<<ans<<endl;
return 0;
}
本文来自博客园,作者:magicat,转载请注明原文链接:https://www.cnblogs.com/magicat/p/16535187.html