菜肴制造(拓扑排序)
Posted wwb123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了菜肴制造(拓扑排序)相关的知识,希望对你有一定的参考价值。
题目描述
输入格式
输出格式
样例
数据范围与提示
这个题想了好久,最后怂了题解,又和身边同学商量一会儿才明白。。。
此题难点在于并不能正序求拓扑顺序,
因为当前选择了一个比较优的点但不能保证它接着找下去会优,
但是换个思维
开个大根堆
我们现在倒序存边时,当前取出的第一个点,这个点代表它是最大的值且他还需要一些条件才能实现
那就无条件把它放在最后输出(因为他是最不优的)
在每次拓扑时将每个top值计入下来,再拓扑后得到新点
每次得到的top值都是当前最差的点
最后倒叙述出就OK了
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 #include<vector> 7 #include<string> 8 #include<queue> 9 #define MAXN 100700 10 #define ll long long 11 #define pt printf("---------\n"); 12 using namespace std; 13 priority_queue<int>q; 14 vector<int>chu[MAXN];int n,m; 15 int ru_du[MAXN],chu_du[MAXN]; 16 int D; 17 int ans[MAXN]; 18 int bian[MAXN]; 19 void work() 20 21 while(!q.empty()) 22 23 int top=q.top(); 24 q.pop(); 25 ans[++ans[0]]=top; 26 bian[top]=1; 27 for(int i=0;i<chu[top].size();++i) 28 29 int to=chu[top][i]; 30 if(bian[to]==1)continue; 31 ru_du[to]--; 32 if(ru_du[to]==0) 33 34 q.push(to); 35 36 37 38 return ; 39 40 int main() 41 42 scanf("%d",&D); 43 for(int k=1;k<=D;++k) 44 45 scanf("%d%d",&n,&m); 46 memset(bian,0,sizeof(bian)); 47 memset(ans,0,sizeof(ans)); 48 for(int i=1;i<=m;++i) 49 50 int x,y; 51 scanf("%d%d",&x,&y); 52 chu[y].push_back(x); 53 ru_du[x]++; 54 55 for(int i=n;i>=1;--i) 56 57 if(ru_du[i]==0) 58 59 q.push(i); 60 61 62 work(); 63 if(ans[0]!=n)printf("Impossible!\n"); 64 else 65 66 for(int i=ans[0];i>=1;--i) 67 68 printf("%d ",ans[i]); 69 70 printf("\n"); 71 72 for(int i=1;i<=n;++i) 73 ru_du[i]=0;chu_du[i]=0;chu[i].clear(); 74 75
以上是关于菜肴制造(拓扑排序)的主要内容,如果未能解决你的问题,请参考以下文章