首先要明确,题意不等价于求最小字典序
例如: n=4,3→1,2→4
此时应输出 3124
因为题目要求的是在保证 1…i 先完成的情况下,再考虑 i+1
所以求反图的最大拓扑字典序即可
示例程序:
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define cl(x,y) memset(x,y,sizeof(x))
using namespace std;
const int maxn=100005;
int tst,n,e,f[maxn],ans[maxn];
int tot,nxt[maxn],son[maxn],lnk[maxn];
priority_queue<int> Q;
inline void add(int x,int y){
son[++tot]=y;nxt[tot]=lnk[x];lnk[x]=tot;
}
int main(){
scanf("%d",&tst);
while (tst--){
scanf("%d%d",&n,&e);
while (!Q.empty()) Q.pop();
cl(lnk,0);tot=0;cl(f,0);
for (int i=1,x,y;i<=e;i++)
scanf("%d%d",&x,&y),add(y,x),f[x]++;
for (int i=1;i<=n;i++)
if (!f[i]) Q.push(i);
ans[0]=0;
while (!Q.empty()){
int x=Q.top();Q.pop();ans[++ans[0]]=x;
for (int j=lnk[x];j;j=nxt[j]){
f[son[j]]--;
if (!f[son[j]]) Q.push(son[j]);
}
}
if (ans[0]<n) printf("Impossible!");else
for (int i=ans[0];i;i--) printf("%d ",ans[i]);
putchar('\n');
}
return 0;
}