拓撲排序 (TopSort)
阿新 • • 發佈:2018-12-01
拓撲排序是DAG(無圈有向圖)引出的新概念,它是對DAG圖的頂點的一種排序。
如果圖中存在兩點 vi --> vj,拓撲排序保證排序結果,vj出現在vi後面。我們可以用這個特性來解決優先順序問題。
而且,如果這個圖有圈,我們的拓撲排序將會失敗。當然拓撲排序結果也並不唯一。
對於拓撲排序,我們先對每一個頂點計算入度,然後將入度為0的頂點放入佇列。當佇列不空,刪除隊首頂點,並把與隊首頂點鄰接的頂點入度-1,在把入度為0的放入佇列。此時拓撲排序就是出隊順序。
#include <cstdio> #include <vector> #include <queue> using namespace std; const int MAX_N=10; //暫且假定圖的 大小 struct GraphVertex{ //鄰接表 vector <int> vertices; }G[MAX_N]; int indegree[MAX_N]; //入度陣列,儲存,每一個頂點的入度 int TopNum[MAX_N]; //拓撲編號陣列儲存每一個頂點的排序編號 void TopSort(int n) { queue <int> q; //設定佇列 int v,counter=0; for (int i=1;i<=n;i++) { if (indegree[i]==0) //入度為 0,放入佇列 q.push(i); } vector<int> :: iterator it; while(!q.empty()) { v=q.front(); q.pop(); printf ("%d ",v); TopNum[v]=++counter;//分配入度編號 for (it=G[v].vertices.begin();it!=G[v].vertices.end();it++) { indegree[*it]--; //對v鄰接的每一個頂點入度-1 if (indegree[*it]==0) //入度為 0,放入佇列 q.push(*it); } } printf ("\n"); if (counter!=n) //只要無法對所有頂點拓撲排序,說明這個不是無圈有向圖。 { printf ("這是個有環圖\n"); } } int main() { int n,u,v,m; scanf ("%d %d",&n,&m); for (int i=0;i<m;i++) { scanf ("%d %d",&u,&v); G[u].vertices.push_back(v); indegree[v]++; } TopSort(n); return 0; }
來幾道例題