POJ4084: 拓扑排序
拓撲排序
1)基本定義
對于一個有向無環圖G=(V,E),V里頂點的線性序列稱作一個拓撲序列,該頂點序列滿足:
- 若在有向無環圖G中從頂點viv_{i}vi?到vjv_{j}vj?有一條路徑,則在序列中頂點viv_{i}vi?一定在vjv_{j}vj?之前
那么對于一個將一個有向無環圖排成拓撲序列的過程就叫做拓撲排序。
2)基本思想
要解決這個問題,首先要理解圖結構入度(in degree)和出度(out degree)的概念。一個點的入度可以大概理解為圖中從其他頂點到該頂點的邊的數目,同理,出度就可以理解為從該點出發到其他頂點的邊的數目。
在我們明確當前圖結構是一個有向無環圖的情況下,從圖中的任意一個頂點出發,在有限步數內不能回到該頂點,那么很顯然,如果有一條從頂點A到達頂點B的路線,在拓撲排序中,頂點A一定位于頂點B之前。如果能理解這個,不難發現,拓撲排序,其實就是把圖結構按照多個樹結構的先根序列進行輸出,不同樹之間輸出的先后順序在拓撲排序中并不重要,因此我們發現,拓撲排序的結果并不唯一。
因此,當一個頂點的入度為0,即沒有一條由其他頂點到達該點的路徑時,可以把該點看做森林中一棵樹的根節點,我們由森林中所有入度為0的點(根節點)依次出發,繼續排序。
由于樹結構的特性,每一個非葉節點,將他與父節點中的連接切斷,就可以看做當前樹結構的一顆子樹的根節點,假設當前頂點時一個入度為1的頂點,他的父節點必然是一個入度為0的頂點,而切斷了他與父節點的連線后,他也成為了一個入度為0的頂點,由此我們發現,將圖結構拓撲排序的過程,就是不斷尋找入度為0的頂點的過程,在尋找到一個入度為0的頂點后,切斷該頂點與子節點間的聯系(子節點入度全部減1),再開始新一輪的搜索,直至所有節點都被輸出為止。
3)代碼實現
#include <iostream> #include <vector> using namespace std;const int MAXN = 1000;首先用順序表實現了一個簡單的有最小堆結構功能的一個數據結構,用來每次彈出當前結構中id最小的值,用最小堆來代替隊列進行拓撲排序,可以改變度數相同的情況下,不同頂點之間的輸出順序問題
class heap {vector<int> lst; public:bool empty() {if (lst.size() == 0)return true;elsereturn false;}void push(int id) {lst.push_back(id);return;}int front() {int minn = lst[0];int minn_pos = 0;for (int i = 0; i < lst.size(); i++) {if (lst[i] < minn) {minn = lst[i];minn_pos = i;}}lst.erase(lst.begin() + minn_pos);return minn;} }; class graph { public://頂點總數int vex;//每個頂點的入度集int in_degree[MAXN];//相鄰矩陣bool relation[MAXN][MAXN];graph(int vex_) :vex(vex_) {for (int i = 1; i <= vex; i++)in_degree[i] = 0;for (int i = 1; i <= vex; i++) {for (int j = 1; j <= vex; j++) {relation[i][j] = 0;}}}~graph() {delete[]in_degree;for (int i = 1; i <= vex; i++)delete[]relation[i];} }; //拓撲排序 void topSort(graph* map) {heap topList;//首先檢索當前圖中入度為0的頂點,將他們壓入最小堆中。for (int i = 1; i <= map->vex; i++) {if (map->in_degree[i] == 0) {topList.push(i);}}while (!topList.empty()) {int current = topList.front();cout << "v" << current << ' ';for (int i = 0; i < map->vex; i++) {if (map->relation[current][i] == 1) {map->in_degree[i]--;if (map->in_degree[i] == 0)topList.push(i);}}}return; }int main() {int v, a;cin >> v >> a;graph* map = new graph(v);int x, y;for (int i = 0; i < a; i++) {cin >> x >> y;if (map->relation[x][y] == 0) {map->relation[x][y] = 1;map->in_degree[y]++;}}topSort(map);cout << endl;return 0; }總結
以上是生活随笔為你收集整理的POJ4084: 拓扑排序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Https中公私钥加密算法和其使用的RS
- 下一篇: 教你自制触摸屏