反向图+拓扑序
本题证法详见黄学长博客。
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std ;
const int N=100010;
int D,n,m;
typedef struct EDGE{
int to,next;
EDGE (){
to=next=0;
}
EDGE (int a,int b){
to=a,next=b;
}
}E;
E edge[N];
int head[N],cnt;
int ind[N];
priority_queue <int> q;
int ans[N],lens,vis[N];
inline void E_add (int u,int v){
edge[++cnt]=EDGE (u,head[v]);
head[v]=cnt;
ind[u]++;
}
void init (){
cin >>D;
}
void readin (){
int i,j,k;
scanf ("%d %d",&n,&m);
for (i=1;i<=m;i++){
scanf ("%d %d",&j,&k);
E_add (j,k);
}
}
void work (){
int i,now,p;
memset (ans,0,sizeof(ans));
lens=0;
for (i=1;i<=n;i++){
if (ind[i]==0) q.push(i);
}
while (!q.empty ()) {
now=q.top ();
q.pop ();
ans[++lens]=now;
for (p=head[now];p;p=edge[p].next){
ind[edge[p].to]--;
if (ind[edge[p].to]==0) q.push (edge[p].to);
}
}
if (lens!=n) {
printf ("Impossible!\n");
return ;
}
else {
for (i=n;i>=1;i--) printf ("%d ",ans[i]);
printf ("\n");
}
}
int main (){
init ();
int i;
for (i=1;i<=D;i++){
memset (ind,0,sizeof (ind));
memset (head,0,sizeof(head));
cnt=0;
readin ();
work ();
}
return 0;
}