Description
![](http://172.16.0.132/uploads/images/dishes.png)
![](http://172.16.0.132/uploads/images/dishes1.png)
Input
![](http://172.16.0.132/uploads/images/dishes2.png)
Output
![](http://172.16.0.132/uploads/images/dishe3.png)
Sample Input
3
5 4
5 4
5 3
4 2
3 2
3 3
1 2
2 3
3 1
5 2
5 2
4 3
Sample Output
1 5 3 4 2
Impossible!
1 5 2 4 3
![](http://172.16.0.132/uploads/images/dishe4.png)
Data Constraint
![](http://172.16.0.132/uploads/images/dishe5.png)
题目本意是求一个拓扑序,使得1尽量靠前,1靠前的前提下2尽量靠前。。。
我们可以反向思考,建立反图,求字典序最大的拓扑序,然后反向输出即可
(对于一个点,我们将比它大且能放它后面的点都尽量放它后面了,这样理解一下)
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<cstring> #include<queue> using namespace std; priority_queue<int> H; int du[100011],g[100011],next[100011],y[100011],ans[100011]; bool vis[100011]; int cnt,dt,tj,i,n,m,x,z,tt; bool pc; void star(int i,int j) { tt++; next[tt]=g[i]; g[i]=tt; y[tt]=j; } void Toplogical() { int l,r,x,j,k,i; pc=true; memset(vis,false,sizeof(vis)); for(i=1;i<=n;i++)if(du[i]==0)H.push(i); while(!H.empty()){ x=H.top(); vis[x]=true; H.pop(); ans[++cnt]=x; j=g[x]; while(j!=0){ k=y[j]; du[k]--; if(du[k]==0)H.push(k); j=next[j]; } } for(i=1;i<=n;i++)if(!vis[i])pc=false; } int main() { scanf("%d",&dt); for(tj=1;tj<=dt;tj++){ memset(g,0,sizeof(g)); tt=0; memset(du,0,sizeof(du)); scanf("%d%d",&n,&m); for(i=1;i<=m;i++){ scanf("%d%d",&x,&z); star(z,x); du[x]++; } while(!H.empty())H.pop(); cnt=0; Toplogical(); if(pc==false)printf("Impossible!\n"); else{ for(i=cnt;i>=1;i--)printf("%d ",ans[i]); printf("\n"); } } }