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 }
View Code

细节:本题开数组大小比较讲究,邻接表的大小不好掌控,开始就RE了一个点。

以上是关于Luogu P1113 杂务 拓扑排序 By cellur925的主要内容,如果未能解决你的问题,请参考以下文章

拓扑排序关键路径

洛谷P1113 杂务

P1113 杂务

ACM入门之图论习题

P1113 杂务

P1113 杂务