第一个拓补排序,写的很烂。 构图之后将第一个入度为0的点压入队列,然后逐个出队列,对于出队列的每个元素将与它相邻的点入度减1,然后找下一个入度为0的点压入队列,代码中的cnt用来判断是否有环。 #include <iostream> #include <queue> using namespace std; const int MAXN=505; int a,b,mat[MAXN][MAXN],list[MAXN],n,m; //mat[][]为1表示i到j连通,list记录排序后的序列 int indegree[MAXN]; //每个点的入度 bool visit[MAXN]; //标记访问 void topsort() { int tmp,cnt=0,sz=0; //cnt在这题没用,因为题目保证有解 queue<int> que; for(int i=1;i<=n;++i) //将第一个入度为0的点压入队列 if(!indegree[i] && !visit[i]) { visit[i]=true; list[sz++]=i; que.push(i); break; } while(!que.empty()) { tmp=que.front(); que.pop(); cnt++; for(int i=1;i<=n;++i) //对于队列出来的每个点将与这个点相邻的点的入度减1 if(mat[tmp][i]) indegree[i]--; for(int i=1;i<=n;++i) //寻找下一个入度为0的点压入队列 if(!indegree[i] && !visit[i]) { visit[i]=true; list[sz++]=i; que.push(i); break; } } } int main() { while(cin>>n>>m) { memset(mat,0,sizeof(mat)); memset(list,0,sizeof(list)); memset(visit,false,sizeof(visit)); memset(indegree,0,sizeof(indegree)); for(int i=0;i<m;++i) { cin>>a>>b; if(!mat[a][b]) //边可能重复给出 { mat[a][b]=1; indegree[b]++; } } topsort(); for(int i=0;i<n;++i) { cout<<list[i]; if(i!=n-1) cout<<' '; } cout<<endl; } return 0; }