先來看乙個實際案例來引出拓撲排序的概念。大學四年有很多課程,假設這些課程表示為c1,c2,…,c12,一共12門課程如下表:
而這些課程的學習順序是有限制的,比如在學習《資料結構》c3之前必須先學習《程式設計基礎》c1和《離散數學》c2,學習《作業系統》c8前必須先學習《資料結構》c3和《計算機組成原理》c6。而學習《程式設計基礎課》c1,和《高等數學》c9不需要其他課程作為基礎。
這樣我們可以用頂點表示課程,有向邊表示先決條件。若課程i是課程j的先決條件則圖中有弧,如下圖
這種頂點表示活動,弧表示活動間優先關係的有向圖稱為頂點表示活動的網,簡稱 aov-網(activity on vertex network)。aov網中不應該出現有向環,因為存在意味著某項頂點活動應該以自己作為先決條件。顯然這是荒謬的!在上面給定課程以及課程的先選條件後,乙個問題是,我們應該如何將所有課程進行排序,使得在學習一門課程時,它的先選課必然已經學過,這就是拓撲排序的內容!
設有向圖g=(v,),g 的拓撲序列是指v中所有頂點的線性序列,該序列滿足如下條件:若g中從頂點vi到頂點vj有一條路徑,則序列中vi必在vj之前。構造有向圖的拓撲序列的過程稱作拓撲排序。通過上面的例子來說就是《資料結構》c3有先選課《程式設計基礎》c1和《離散數學》c2,那麼拓撲排序後的線性序列中必有c1,c2在c3之前!
拓撲排序的方法:
1.從有向圖中選取乙個沒有前驅的頂點(入度為0),並輸出之;
2. 從有向圖中刪去此頂點以及所有以它為尾的弧;
3. 重複上述兩步,直至全部頂點均已輸出,或者圖中找不到無前驅的頂點為止。
————————————————————————————————————————
對於任意的有向圖,拓撲排序不一定成功,如果有向圖含有環,則不能得到其拓撲序列。
例如,對於下列有向圖,如果對其進行拓撲排序,在輸出a之後,會因為圖中沒有入度為0的點而結束,此時拓撲排序只有1個點,所以對於乙個圖進行拓撲排序,如果拓撲排序結果中的點小於圖中點的個數,那麼這個圖就是有環圖!所以拓撲排序可以用來檢測乙個有向圖中是否有環。
不能求得它的拓撲序列。因為圖中存在迴路 ( b, c, d )
假設有如下的有向圖,可以看到點a,b沒有前驅(入度為0),假設我們選擇a作為第乙個點(此時選擇點b作為第乙個點也是可行的,所以拓撲排序不唯一)
選擇a後,刪除以a為尾的弧(出去的邊),此時點b,c入度為0,假設下一步選擇點b
刪除以b為尾的弧,此時點c,g,h入度為0,假設下一步選擇點h
刪除以h為尾的弧,此時點c,g入度為0,假設下乙個點選擇c
刪除以c為尾的弧,此時只有點d的入度為0,下一步選擇點d
刪除以d為尾的弧,此時只有點g的入度為0,下一步選擇點g
刪除以g為尾的弧,此時只有f的入度為0,下一步選擇f
刪除以f為頂點的弧,此時只有e的入度為0,下一步選擇e,最後得到了拓撲排序a,b,h,c,d,g,f,e
以上就是拓撲排序的過程
vector<
int>
topologicla_sort
(vector
int>
>
&map)
}while
(!q.
empty()
) map[point]
[i]=0;
//刪除該條邊}}
}return result;
}
hdoj 1285, 我的題解
hdoj 3342, 我的題解
hdoj 2647,我的題解
拓撲排序入門
拓撲排序性質 1拓撲排序只有在有向無環圖中才能排出有效的序列,因此可以通過拓撲排序判斷該圖是否為有向有環圖。2 如果輸入的有向圖中的點,不存在入度為0的點,則該有向圖存在迴路 3 如果存在的入度為0的點大於乙個,不妨礙拓撲排序 可以得到多種拓撲排序的結果 拓撲排序的步驟 1.在有向圖中選乙個沒有入度...
拓撲排序(入門)
參考部落格 入門拓撲排序 在乙個有向圖中,對所有的節點進行排序,要求沒有乙個節點指向它前面的節點。先統計所有節點的入度 作為終點被指向的次數 對於入度為0的節點就可以分離出來,然後把這個節點指向的節點的入度減一。一直更新,直到所有的節點都被分離出來。如果最後不存在入度為0的節點,那就說明有環,不存在...
新手入門 拓撲排序
o o o哈!上個月學的拓撲排序,曾經覺得它很高深.今天就寫篇簡單的入門.也當是給自己複習好了 咱們不用那些陌生的名詞.咱們通俗點講.介個演算法是解決甚麼問題的呢?實際中,我們經常會碰到到這樣一類問題 一堆元素,不一定每兩個間都有嚴格的先後關係.先前的冒泡,快速排序等等等等都是建立在 每兩個元素間都...