演算法錄 之 拓撲排序和尤拉路徑。

2022-08-02 09:24:10 字數 1853 閱讀 1007

1:

問題:對於乙個dag(有向無環圖),求點的排序,使得排在後面的點不能通過一條路徑到前面的點。

如圖,他的其中乙個拓撲排序是 1,2,3,4,5,但是1,2,5,3,4不行,因為3能到5。

求解演算法:

可以看出如果某個點有入邊,也就是有其他的點能夠到這個點,那麼顯然這個點不能被放在開頭。所以就需要先找到乙個入度為0的點放在開頭,然後刪掉這個點和這個點連線的所有的邊,然後對剩下的圖遞迴求解就ok了。

然後實現方法類似bfs,把所有入度為0的點加入佇列,然後每次取出隊首的點放入答案陣列中,然後刪掉所有從這個點出發的邊後,把新產生的入度為0的點加入。

偽**如下:

1 vector rank() 18}

1920

return

ans;

21 }

複雜度的話,因為每個點最多遍歷一次,每個點的每條邊也是。

所以複雜度是 n+m (m是邊數)。

2:問題:

求乙個無向圖的一條尤拉路?也就是是否可以一筆畫完?

先判斷圖是否存在尤拉路,不存在直接返回。根據尤拉的定理:如果乙個無向圖有三個或者三個以上的點的度數是奇數,就沒有尤拉路。

先找到degree為奇數的乙個點(不存在的話就任意點)作為開始點,進行dfs,每次走過一條邊之後就刪除這條邊。然後當某個點無路可走的時候,把這個點加入答案陣列。

最後答案陣列反向就是答案。

偽**如下:

1 vector ans;23

void dfs(int

u) 10}11

}1213void

geteuler()

例圖如下:

從1開始dfs,找到1-2的邊,刪除,dfs 點2      然後找到邊2-3,刪除,dfs 點3

然後找到邊1-3,刪除,dfs 點1。      這時dfs 點1無路可走,把1加入ans。然後回溯到3,  然後找到邊4-5,刪除,dfs 點5。

找到邊3-4,刪除,dfs 點4。

然後找到邊5-3,刪除,dfs 點3        然後3無路可走,加入ans,回溯到5,然後5無路可走,加入ans,回溯到4,然後4無路可走,加入ans,回溯到3,然後3無

路可走,加入ans,回溯到2,然後2無路可走,加入ans,回溯到1,然後1無路可走,加入ans。

這時ans陣列是 1,3,5,4,3,2,1。

倒序的話就是一條尤拉路。

至於正確性的證明,嚴密的證明不會,但是如果乙個點邊很少的話一定要盡量往後被訪問,不然進去就出不來了。所以這算是半個貪心策略,嗯。

尤拉迴路和尤拉路徑

幾個入門的題目 hdu 1878 判定乙個圖是否存在尤拉迴路。直接判斷圖是否連通和每個點的度數是否為偶數就行了。可用並查集判斷連通,也可以用dfs include include include include using namespace std const int maxn 1100 int ...

尤拉路徑和尤拉迴路的路徑

尤拉路徑和尤拉迴路 尤拉路徑 從某結點出發一筆畫成所經過的路線叫做尤拉路徑。尤拉迴路 在尤拉路徑的基礎上又回到起點。a 凡是由偶點組成的連通圖,一定可以一筆畫成。畫時可以把任一偶點為起點,最後一定能以這個點為 終點畫完此圖。b 凡是只有兩個奇點的連通圖 其餘都為偶點 一定可以一筆畫成。畫時必須把乙個...

Hierholzer演算法尋找尤拉路徑

什麼是尤拉路徑?尤拉路徑就是一條能夠不重不漏地經過圖上的每一條邊的路徑,即小學奧數中的一筆畫問題。而若這條路徑的起點和終點相同,則將這條路徑稱為尤拉迴路。查詢尤拉路徑可以使用hierholzer演算法,以下題為例講解一下hierholzer演算法。leetcode332重新安排 題目大意 給一組邊 ...