BZOJ4010: [HNOI2015]菜肴制作
【传送门:BZOJ4010】
简要题意:
有n道菜,有m个限制条件,每个限制条件输入x,y,表示第x道菜要在第y道菜之前做
在满足所有限制条件的情况下,编号小的菜要尽早做
求出满足要求的菜的顺序,如果没有满足要求的则输出Impossible!
题解:
拓扑排序
一开始想着将x连向y,然后跑拓扑,输出字典序最小的序列
结果发现题目并不是要求字典序最小,而是要求较小的尽量靠前
那就跑逆拓扑序,然后倒着输出就好了
因为等价于倒着的字典序最大,因为字典序最大相当于小的尽量靠后,即正着的小的尽量靠前。
参考代码:
#include<cstdio> #include<cstring> #include<cstring> #include<algorithm> #include<queue> using namespace std; struct node { int x,y,d,next; }a[110000];int len,last[110000]; int ru[110000],s[110000]; bool v[110000]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } priority_queue<int>q; int main() { int T; scanf("%d",&T); while(T--) { int n,m; scanf("%d%d",&n,&m); len=0;memset(last,0,sizeof(last)); memset(ru,0,sizeof(ru)); for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); ins(y,x); ru[x]++; } memset(v,true,sizeof(v)); bool bk=false; for(int i=1;i<=n;i++) if(ru[i]==0) q.push(i); int t=0; while(q.empty()==0) { int x=q.top();q.pop(); s[++t]=x; v[x]=false; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; ru[y]--; if(ru[y]==0) q.push(y); } } if(t!=n) printf("Impossible!"); else for(int i=n;i>=1;i--) printf("%d ",s[i]); printf("\n"); } return 0; }
渺渺时空,茫茫人海,与君相遇,幸甚幸甚