關於拓撲排序

2022-03-06 22:23:41 字數 2764 閱讀 3331

拓撲排序

英文名稱:topological-sort

別稱:toposort or  topsort

以下進入胡扯時間 正題:

排序???

a:我有sort!

b:我還會桶排!

c:我我我!我還會基數排序和計數排序

哇塞!厲害!

但是你會這些東西和我拓撲排序有什麼關係

a??b??c???

拓撲排序是幹什麼的呢

以上來自360百科

看明白了嗎,反正我是不想看

嗯!這才是正題。

首先,我們由乙個小問題引入。

有這麼一群人,小紅愛著小綠,她得親眼看著小綠吃完飯她才會安心吃飯,

而這個時候,小黃也愛著小綠,他也要親眼看著小綠把飯吃完她才會安心。

同時,小藍愛著小紅和小黃,她得親眼看著小紅和小黃吃完飯她才可以吃飯,

而小紫是個基佬,他不愛小紅,不愛小黃,不愛小藍,也不愛小綠,正因為他是基佬所以他對小紅小黃毫無威脅性,

於是小紫可以同小綠一起吃飯,當然也不可以不。

那麼最終,大家吃飯的順序是怎樣的呢。 

形象一點,畫個圖

大佬們看到這個小問題:這個sb題!這不是分分鐘秒切的事情嗎!

像我這種小菜雞:誒??爆搜嗎?

爆搜??什麼zz做法。別說,還真有點意思。

不過我們首先講的,是kahn演算法,一看這個演算法就很高階對不對!

對什麼對,只是聽起來高階而已。

其演算法主要流程如下:

1.從圖中找到乙個入度為零的點,並輸出

2.在圖中刪去和這個點相連的所有邊,再重複1的操作

3.一直重複1.2的操作一直到圖中不再有入度不為零的點為止。

當然,如果圖中有環那是無解的。

那麼它的複雜度是多少呢?

你猜你猜你猜

證明:初始化入度為0的集合需要遍歷整張圖,檢查每個節點和每條邊,對該集合進行操作,又需要遍歷整張圖中的,每條邊,則複雜度為o(e+v);

**:

#include#include

#include

#include

#include

#include

using

namespace

std;

typedef

long

long

ll;const

int maxn = 1000 + 10

;const

int inf = 1e9 + 7

;int

t, n, m, num[maxn];

vector

vis[maxn], v;

stack

s;void

topo()

if(v.size() != n) cout << "

no solution

"<< '\n'

;

else

for(int i = 0; i < v.size(); i++) cout

}int

main()

現在我們再來講基於dfs的演算法

需要注意的是,將頂點新增到結果anst中的時機是在vis方法即將退出之時。

搜尋嘛,實踐略簡單,但是理解上要下點功夫。

其關鍵在於為什麼在vis方法的最後將該頂點新增到乙個集合中,就能保證這個集合就是拓撲排序的結果?

因為新增頂點到集合中的時機是在dfs方法即將退出之時,而dfs方法本身是個遞迴方法,只要當前頂點還存在邊指向其它任何頂點,它就會遞迴呼叫dfs方法,而不會退出。因此,退出dfs方法,意味著當前頂點沒有指向其它頂點的邊了,即當前頂點是一條路徑上的最後乙個頂點。

那麼問題來了,這個方法對嗎?

你猜你猜你猜

證明:考慮任意的邊,當呼叫dfs(v)的時候,有三種情況:

需要注意的是,以上第三種情況在拓撲排序的場景下是不可能發生的,因為如果情況3是合法的話,就表示存在一條由w到v的路徑。而現在我們的前提條件是由v到w有一條邊,這就導致我們的圖中存在環路,從而該圖就不是乙個有向無環圖(dag),而我們已經知道,非有向無環圖是不能被拓撲排序的。

那麼考慮前兩種情況,無論是情況1還是情況2,w都會先於v被新增到結果列表中。所以邊v->w總是由結果集中後出現的頂點指向先出現的頂點。為了讓結果更自然一些,可以使用棧來作為儲存最終結果的資料結構,從而能夠保證邊v->w總是由結果集中先出現的頂點指向後出現的頂點。

時間複雜度:

證明:dfs遍歷一遍的時間為o(e+v),而記錄結果的時間花費為o(1),所以總時間複雜度為o(e+v)

**:

#include#include

#include

#include

#include

using

namespace

std;

const

int maxn = 1000 + 10

;const

int inf = 1e9 + 7

;int

n, m, dis[maxn], ans[maxn], t;

vector

vis[maxn];

bool dfs(int

u) dis[u] = 1, ans[--t] =u;

return

true;}

bool

toposort()

intmain()

一世安寧

關於拓撲排序的筆記

一.關於拓撲排序的背景 根據我的的理解,一些事件的發生順序是互相聯絡的,比如事件a需要在事件b發生完畢之後才可能發生,可以說b是a的前驅事件。例如大學中的課程設定,要學習演算法設計這麼課程,就要先學習資料結構。因此,我們上課的順序是依賴某些課程之間的關係的,當然,這種順序並不唯一,例如計算機網路和計...

python 拓撲排序 Python 拓撲排序

python 拓撲排序 在圖論中,由乙個有向無環圖的頂點組成的序列,當且僅當滿足下列條件時,稱為該圖的乙個拓撲排序 英語 topological sorting 每個頂點出現且只出現一次 若a在序列中排在b的前面,則在圖中不存在從b到a的路徑。print 拓撲排序結果 g.topologicalso...

python 排序 拓撲排序

在電腦科學領域中,有向圖的拓撲排序是其頂點的先行排序,對於每個從頂點u到頂點v的有向邊uv,在排序的結果中u都在v之前。如果圖是有向無環圖,則拓撲排序是可能的 為什麼不說一定呢?圖論 是組合數學的乙個分支,它和其他分支比如 群論 拓撲學 矩陣論有著密切的關係。圖是圖論的主要研究物件。圖是由若干給定的...