题意:有n件家务要做,其中有些要在某些做完后才能做,几件家务可以一起做,问最少时间。
思路:拓扑排序,找最长路径。
这里我添加了1个0节点,然后A到B的权值表示做B的时间。拓扑排序时从0开始即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int fst[10005],next[1000005],node[1000005],l[1000005],en;
int d[10005],n,len,k,ans,in[10005];
void add(int u,int v,int ll)
{
next[++en]=fst[u];
fst[u]=en;
node[en]=v;
l[en]=ll;
}
void topsort()
{
memset(d,0,sizeof(d));
queue<int>q;
q.push(0);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=fst[u];i!=-1;i=next[i])
{
int v=node[i];
d[v]=max(d[v],d[u]+l[i]);
in[v]--;
if(!in[v])
{
q.push(v);
}
}
}
}
int main()
{
int u;
en=0;
memset(fst,-1,sizeof(fst));
memset(in,0,sizeof(in));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&len);
scanf("%d",&k);
if(k==0)
{
add(0,i,len);
in[i]++;
}
else
{
for(int j=0;j<k;j++)
{
scanf("%d",&u);
add(u,i,len);
in[i]++;
}
}
}
topsort();
ans=0;
for(int i=1;i<=n;i++)
{
if(d[i]>ans)ans=d[i];
}
cout<<ans<<endl;
return 0;
}