1)基本定義
對於乙個有向無環圖g=(v,e),v裡頂點的線性序列稱作乙個拓撲序列,該頂點序列滿足:
那麼對於乙個將乙個有向無環圖排成拓撲序列的過程就叫做拓撲排序。
2)基本思想
要解決這個問題,首先要理解圖結構入度(in degree)和出度(out degree)的概念。乙個點的入度可以大概理解為圖中從其他頂點到該頂點的邊的數目,同理,出度就可以理解為從該點出發到其他頂點的邊的數目。
在我們明確當前圖結構是乙個有向無環圖的情況下,從圖中的任意乙個頂點出發,在有限步數內不能回到該頂點,那麼很顯然,如果有一條從頂點a到達頂點b的路線,在拓撲排序中,頂點a一定位於頂點b之前。如果能理解這個,不難發現,拓撲排序,其實就是把圖結構按照多個樹結構的先根序列進行輸出,不同樹之間輸出的先後順序在拓撲排序中並不重要,因此我們發現,拓撲排序的結果並不唯一。
因此,當乙個頂點的入度為0,即沒有一條由其他頂點到達該點的路徑時,可以把該點看做森林中一棵樹的根節點,我們由森林中所有入度為0的點(根節點)依次出發,繼續排序。
由於樹結構的特性,每乙個非葉節點,將他與父節點中的連線切斷,就可以看做當前樹結構的一顆子樹的根節點,假設當前頂點時乙個入度為1的頂點,他的父節點必然是乙個入度為0的頂點,而切斷了他與父節點的連線後,他也成為了乙個入度為0的頂點,由此我們發現,將圖結構拓撲排序的過程,就是不斷尋找入度為0的頂點的過程,在尋找到乙個入度為0的頂點後,切斷該頂點與子節點間的聯絡(子節點入度全部減1),再開始新一輪的搜尋,直至所有節點都被輸出為止。
3)**實現
#include
#include
using
namespace std;
const
int maxn =
1000
;
首先用順序表實現了乙個簡單的有最小堆結構功能的乙個資料結構,用來每次彈出當前結構中id最小的值,用最小堆來代替佇列進行拓撲排序,可以改變度數相同的情況下,不同頂點之間的輸出順序問題
class
heap
void
push
(int id)
intfront()
} lst.
erase
(lst.
begin()
+ minn_pos)
;return minn;}}
;
class
graph}}
~graph()
};//拓撲排序
void
topsort
(graph* map)
}while
(!toplist.
empty()
)}}return;}
intmain()
}topsort
(map)
; cout << endl;
return0;
}
POJ 1094 拓撲排序
文章大意是將n個字母排序 n 26 最終必須排成鍊錶式的輸出 一旦確定或者出現環,記錄當前步數,後續輸入無視 加個拓撲排序判斷圖的總結 1 如果輸入的有向圖中的點,不存在入度為0的點,則存在迴路,反過來則不成立 2 如果入隊的點的個數小於輸入的點的個數,則肯定存在迴路 3 如果存在的入度為零的點大於...
拓撲排序 poj1094
此題題目有點小問題,那也是很多人ac不了的原因 問題是,當給定的前k項條件能夠確定出大小順序時,即便k項之後出現了矛盾條件,輸出也應該是sorted sequence determined after k relations 後面再輸出排序好的序列!include include using nam...
POJ 1094 拓撲排序)
拓排 各種判 program p1094 type map3 record indegree array a z of longint map array a z 1.26 of char outdegree array a z of longint end var n,m,i,j,num,valu...