码迷,mamicode.com
首页 > 编程语言 > 详细

Luogu P1113 杂务 【拓扑排序】 By cellur925

时间:2018-08-14 23:31:02      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:spl   src   val   main   而在   dag   closed   problem   one   

题目传送门

这题我们一看就知道是拓扑排序,然而在如何转化问题上花了大工夫,一个小时后最后还是无奈看了题解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

标签:spl   src   val   main   而在   dag   closed   problem   one   

原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9478629.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!