1. 程式人生 > >模板:拓撲排序

模板:拓撲排序

所有 spa dag圖 queue false 原理 set true 節點

原理:

1.從DAG圖中選一個 沒有前驅(即入度為0)的頂點並輸出
2.從圖中刪除該頂點和所有以它為起點的有向邊
3.重復1和2直到當前的DAG為空或當前圖中不存在無前驅的頂點為止,後一種情況說明有向圖中一定有環。

 1 int n;
 2 int in[N];
 3 bool E[N][N];
 4 queue <int> Q;
 5 
 6 void toposort(){
 7     for(int i=1;i<=n;i++){
 8         //尋找入度為0的點
 9         int j=1;
10         while(in
[j]!=0) j++; 11 in[j]--; 12 Q.push(j); 13 //將關聯的點的入度減1,即刪除與該節點關聯的邊 14 for(int k=1;k<=n;k++){ 15 if(E[j][k]) in[k]--; 16 } 17 } 18 }

拓撲排序判環:

 1 //n^2判環
 2 
 3 int n;
 4 const int N=5e2+10;
 5 int E[N][N],vis[N];//vis[i]=0,-1,1分別表示未訪問、正在訪問、已訪問並且已遞歸訪問完所有子孫
6 7 bool dfs(int u){ 8 vis[u]=-1; 9 for(int i=1;i<=n;i++){ 10 if(E[u][i]){ 11 if(vis[i]<0) return false; 12 else if(!vis[i]&&!dfs(i)) return false; 13 } 14 } 15 vis[u]=1; 16 ans.push(u); 17 return true; 18
} 19 20 bool toposort(){ 21 memset(vis,0,sizeof(vis)); 22 for(int i=1;i<=n;i++){ 23 if(!vis[i]){ 24 if(!dfs(i)) return false; 25 } 26 } 27 return true; 28 }

模板:拓撲排序