枚举做法,然后发现这个就是倒序输出反图的字典序最大拓扑排序
证明的话大概就是对于一个标号小的点,我们肯定需要大于它的标号尽可能都在他前面,它前面的越多,逆序之后它就越靠前
<span style="font-size:18px;">#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int N=100000+5; struct Edge{int to,next;}e[N]; int head[N],cnt; void ins(int u,int v){ e[++cnt]=(Edge){v,head[u]};head[u]=cnt; } int deg[N]; priority_queue<int>q; int a[N],tot; void solve(int u){ q.pop();a[++tot]=u; for(int i=head[u];i;i=e[i].next){ int v=e[i].to; deg[v]--; if(!deg[v])q.push(v); } } int main(){ //freopen("a.in","r",stdin); int T;scanf("%d",&T); while(T--){ int n,m;scanf("%d%d",&n,&m); memset(deg,0,sizeof(deg)); memset(head,0,sizeof(head));cnt=0; while(m--){ int u,v;scanf("%d%d",&u,&v);ins(v,u); deg[u]++; } while(!q.empty())q.pop(); for(int i=1;i<=n;i++)if(!deg[i])q.push(i); tot=0; while(!q.empty())solve(q.top()); if(tot!=n)puts("Impossible!"); else{ for(int i=n;i;i--) printf("%d ",a[i]); putchar('\n'); } } return 0; }</span>