Luogu P1113 杂务 拓扑排序 By cellur925
Posted nopartyfoucaodong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu P1113 杂务 拓扑排序 By cellur925相关的知识,希望对你有一定的参考价值。
这题我们一看就知道是拓扑排序,然而在如何转化问题上花了大工夫,一个小时后最后还是无奈看了题解qwq。
显然我们可以对于每个任务,从他的前导任务到他连一条边,最后我们可以得到一个DAG。在这个DAG上进行拓扑排序,更新做到第j号任务的花费,花费就是max(f[j],f[i]+val[j])。当我们找到一个出度为0的点,就可以用它更新最终答案。
code
1 #include<cstdio> 2 #include<algorithm> 3 #include<queue> 4 5 using namespace std; 6 7 int n,ans,tot,cnt; 8 int val[10090],du[10090],head[10090],f[10090],cdu[10090]; 9 struct node{ 10 int next,to; 11 }edge[200900]; 12 13 void add(int x,int y) 14 { 15 edge[++tot].next=head[x]; 16 head[x]=tot; 17 edge[tot].to=y; 18 } 19 20 void topo() 21 { 22 queue<int>q; 23 for(int i=1;i<=n;i++) 24 if(du[i]==0) q.push(i),f[i]=val[i]; 25 while(!q.empty()) 26 { 27 int x=q.front();q.pop(); 28 for(int i=head[x];i;i=edge[i].next) 29 { 30 int y=edge[i].to; 31 f[y]=max(f[y],f[x]+val[y]); 32 if(--du[y]==0) 33 { 34 if(!cdu[y]) ans=max(ans,f[y]); 35 else q.push(y); 36 } 37 } 38 } 39 } 40 41 int main() 42 { 43 scanf("%d",&n); 44 for(int i=1;i<=n;i++) 45 { 46 int opt=0,y=0; 47 scanf("%d%d",&opt,&val[i]); 48 while(scanf("%d",&y)&&y!=0) add(opt,y),du[y]++,cdu[opt]++; 49 } 50 topo(); 51 printf("%d",ans); 52 return 0; 53 }
细节:本题开数组大小比较讲究,邻接表的大小不好掌控,开始就RE了一个点。
以上是关于Luogu P1113 杂务 拓扑排序 By cellur925的主要内容,如果未能解决你的问题,请参考以下文章