输出字典序最小的拓扑序,从1到n遍历,每次碰到入度为0的点就入队,然后立刻break,再把它的出边都删掉,然后再从1到n遍历,碰到入度为0的点就入队,再break。每次只入队一个,这样能保证字典序最小。
#include<bits/stdc++.h>
using namespace std;
const int N=505;
int cnt,n,m,du[N];
bool g[N][N];
queue<int>q;
void topo(){
for(int i=1;i<=n;++i){
if(!du[i]){
q.push(i);
break;
}
}
bool mark=1;//控制输出的空格
while(!q.empty()){
int t=q.front();
q.pop();
du[t]=-1;//防止后面重复入队
if(mark){
printf("%d",t);
mark=0;
}else{
printf(" %d",t);
}
for(int i=1;i<=n;++i){//删除所有出边
if(g[t][i]) du[i]--;
}
for(int i=1;i<=n;++i){
if(!du[i]){
q.push(i);
break;
}
}
}
puts("");
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
memset(g,0,sizeof g);
memset(du,0,sizeof du);
for(int i=0;i<m;++i){
int a,b;
scanf("%d%d",&a,&b);
if(!g[a][b]){//重边不计
g[a][b]=true;
du[b]++;
}
}
topo();
}
}