判斷有向圖是否有環及拓撲排序
阿新 • • 發佈:2019-01-06
對一個有向無環圖(Directed Acyclic Graph簡稱DAG)G進行拓撲排序,是將G中所有頂點排成一個線性序列,使得圖中任意一對頂點u和v,若邊(u,v)∈E(G),則u線上性序列中出現在v之前。通常,這樣的線性序列稱為滿足拓撲次序(Topological Order)的序列,簡稱拓撲序列。
一個較大的工程往往被劃分成許多子工程,我們把這些子工程稱作活動(activity)。在整個工程中,有些子工程(活動)必須在其它有關子工程完成之後才能開始,也就是說,一個子工程的開始是以它的所有前序子工程的結束為先決條件的,但有些子工程沒有先決條件,可以安排在任何時間開始。為了形象地反映出整個工程中各個子工程(活動)之間的先後關係,可用一個有向圖來表示,圖中的頂點代表活動(子工程),圖中的有向邊代表活動的先後關係,即有向邊的起點的活動是終點活動的前序活動,只有當起點活動完成之後,其終點活動才能進行。
// Topological_Sort.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include<vector> #include<iostream> using namespace std; #define N 9 typedef struct{ int vexnum, arcnum; char vexs[N]; int matirx[N][N]; }graph; graph g; int re[N]; // 初始化圖資料 // 0---1---2---3---4---5---6---7---8--- // A---B---C---D---E---F---G---H---I--- void initiate_graph() { // A-B, A-D, A-E g.matirx[0][1] = 1; //g.matirx[1][0] = 1; g.matirx[0][3] = 1; //g.matirx[3][0] = 1; g.matirx[0][4] = 1; //g.matirx[4][0] = 1; // B-C //g.matirx[1][2] = 1; g.matirx[2][1] = 1; // C-F g.matirx[2][5] = 1; //g.matirx[5][2] = 1; // D-E, D-G g.matirx[3][4] = 1; //g.matirx[4][3] = 1; //g.matirx[3][6] = 1; g.matirx[6][3] = 1; // E-F, E-H g.matirx[4][5] = 1; //g.matirx[5][4] = 1; //g.matirx[4][7] = 1; g.matirx[7][4] = 1; // F-H, F-I //g.matirx[5][7] = 1; g.matirx[7][5] = 1; //g.matirx[5][8] = 1; g.matirx[8][5] = 1; // G-H g.matirx[6][7] = 1; //g.matirx[7][6] = 1; // H-I g.matirx[7][8] = 1; //g.matirx[8][7] = 1; } //判斷有向圖是否有環 bool is_cycle(graph g) { int k = 0; while (k < N) { int a[N] = { 0 }; a[k] = 1; vector<int>aa,cycle; cycle.push_back(k); vector<vector<int>>bb; for (int i = 0; i < N; i++) if (g.matirx[k][i]) aa.push_back(i); if (!aa.empty()) { bb.push_back(aa); while (!bb.empty()) { while ((bb.back()).empty()) { bb.pop_back(); a[cycle.back()] = 0; cycle.pop_back(); if (bb.empty()) break; } if (bb.empty()) break; int m = (bb.back()).back(); (bb.back()).pop_back(); a[m] = 1; cycle.push_back(m); vector<int>cc; for (int i = 0; i < N; i++) if (g.matirx[m][i]) { if (a[i] == 1) return true; cc.push_back(i); } if (!cc.empty()) bb.push_back(cc); else { a[m] = 0; cycle.pop_back(); } } } k++; } return false; } void topological_sort(graph g) { int aa[N] = { 0 }; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) { if (g.matirx[j][i]) aa[i]++; } int k = 0; while (k < N) { for (int i = 0; i < N; i++) if (aa[i] == 0) { re[k] = i; aa[i] = -1; for (int j = 0; j < N; j++) { if (g.matirx[i][j]) aa[j]--; } k++; break; } } } int _tmain(int argc, _TCHAR* argv[]) { initiate_graph(); if (!is_cycle(g)) topological_sort(g); system("pause"); return 0; }