kahn算法
#include <bits/stdc++.h> const int maxn=100+5,maxm=1e4+5; struct Node{int to;int next;}e[maxm]; int n,m,len,head[maxn],rd[maxn],a[maxn]; void Insert(int x,int y){ e[++len].to=y;e[len].next=head[x];head[x]=len; } void Kahn(){ std::stack<int> q; for(int i=1;i<=n;++i)//入度为0的点进栈 if(!rd[i])q.push(i); int cnt=0;//计算出栈点的个数 while(!q.empty()){ int u=q.top();q.pop();a[++cnt]=u; for(int i=head[u];i;i=e[i].next){ int v=e[i].to;rd[v]--;//相当于删除u的邻接边 if(!rd[v])q.push(v); } } if(cnt<n){//说明有环 printf("Cycle\n");return; } for(int i=1;i<=cnt;++i) printf("%d ",a[i]); } void Solve(){ scanf("%d%d",&n,&m);//n个点m条边有向图 for(int i=1;i<=m;++i){ int x,y;scanf("%d%d",&x,&y); Insert(x,y);rd[y]++; } Kahn(); } int main(){ Solve(); return 0; }
基于dfs的算法
#include <bits/stdc++.h> const int maxn=100+5,maxm=1e4+5; struct Node{int to;int next;}e[maxm]; int n,m,len,cycle,head[maxn],rd[maxn],vis[maxn]; std::stack<int>q; void Insert(int x,int y){ e[++len].to=y;e[len].next=head[x];head[x]=len; } void dfs(int u){ if(cycle==1)return;//如果已经存在环强制退出 vis[u]=-1;//u设为灰点 for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(!vis[v])dfs(v); else if(vis[v]==-1){//此时v如果为灰点说明<u,v>是反向边 printf("Cycle\n");cycle=1;return; }//return只能退出一个递归 } vis[u]=1;q.push(u);//u变黑说明无路可走,进栈 } void Solve(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;++i){ int x,y;scanf("%d%d",&x,&y); Insert(x,y);rd[y]++; } for(int i=1;i<=n;++i)//有可能是非连通图 if(!rd[i])dfs(i); if(cycle==0)//无环则输出拓扑排序 while(!q.empty()){ printf("%d ",q.top());q.pop(); } } int main(){ Solve(); return 0; }