传送门
题意:有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; }