拓撲排序(判斷是否是有向無環圖)
阿新 • • 發佈:2019-01-02
要進行拓撲排序之前,該圖要是有向無環圖。
排序方法:
1、從有向圖中選取一個沒有前驅的頂點,並輸出之
;2、從有向圖中刪去此頂點以及所有以它為尾的弧;
3、重複上述兩步,直至圖空,或者圖不空但找不到無前驅的頂點為止。
而拓撲排序 只要將上面的陣列kj[]從小到大輸出即可。#include<stdio.h> #include<string.h> #include<iostream> using namespace std; const int maxn=100001; const int inf=1<<29; int e,head[maxn],pnt[maxn],nxt[maxn]; int cnt_in[maxn],cnt_out[maxn]; bool vis[maxn]; int n,m,k; void AddEdge(int u,int v) { pnt[e]=v;nxt[e]=head[u];head[u]=e++; } int main() { int tt; scanf("%d",&tt); while(tt--) { scanf("%d%d",&n,&m); e=0; memset(head,-1,sizeof(head)); memset(cnt_in,0,sizeof(cnt_in)); memset(cnt_out,0,sizeof(cnt_out)); memset(vis,0,sizeof(vis)); for(int i=0;i<m;i++) { int u,v; scanf("%d%d",&u,&v); AddEdge(u,v); cnt_out[u]++; cnt_in[v]++; } /*for(int i=1;i<=n;i++) { printf("%d :",i); printf("%d %d\n",cnt_in[i],cnt_out[i]); }*/ int cnt=0; int kj[maxn]; while(1) { int f=0; for(int u=1;u<=n;u++) { if(cnt_in[u]==0&&!vis[u]) { f=1; for(int i=head[u];i!=-1;i=nxt[i]) { cnt_in[pnt[i]]--; } kj[cnt++]=u; vis[u]=1; } } if(cnt==n||f==0) break; } int k2=0; for(int i=1;i<=n;i++)//如果所有的數字的入度都為0,代表這是一個無環圖。 if(vis[i]==0) k2=1; if(k2==1) puts("Wrong"); else puts("Correct"); } return 0; }
for(int i=0;i<cnt;i++)
printf("%d ",kj[i]);