圖的題目歸類總結

類別

題目

並查集

261, 323, 684

最短路徑

743

最小生成樹

1135

拓撲排序

207, 210, 802,310

關鍵路徑法

圖的知識點補充(AOE網絡的關鍵路徑)

圖的遍歷

133, 332(歐拉路徑), 399, 785, 841, 997, 1042, 1306

其它

959, 1043, 1161, 1267, 444

就不貼題目超鏈接了,可以去請看這裏!!!leetcode題目目錄!!根據題號找對應題目。

 

歸納總結:

一、圖的遍歷(traversing of graph)

1、主要就是dfs(depth-first search)、bfs(breadth-first search)。

2、樣例代碼,請參考:841. 鑰匙和房間

 

 

二、並查集(Union-Find)

1、找老大,老大是自己的頂點是該聯通域的掌門人。

2、集合的合併,如果一條邊的兩個頂點老大一樣,說明這兩個頂點原本就在一個聯通域內,該聯通域內有環;如果一條邊的兩個頂點老大不一樣,那麼就要把他們併到一個集合內。

3、最後,老大的數目決定連通域的個數。

4、樣例代碼,請參考:684. 冗餘連接(並查集)

 

 

三、拓撲排序(topological sort)

1、採用鄰接表來表示有向圖,抽象成:

(1)一個二維數組,裏面每一個一維數組存以該索引爲頂點的後繼頂點。

(2)一個一維數組 in, 來表示每個頂點的入度數目。

2、我們開始先根據輸入來建立這個有向圖,並將入度數組也初始化好。

3、設置一個stack:

(1)將所有入度爲0的點壓棧。

(2)從棧中退出棧頂元素輸出,並把該頂點引出的所有有向邊刪去,也就是把它的各個鄰接頂點的入度數-1。

(3)將新的入度數爲零的頂點再入堆棧。

(4)重複過程(2)-(3),直到棧爲空。

4、最後,如果已經輸出全部頂點,所有頂點入度數都爲0,說明有向圖中不存在環;如果沒有輸出全部頂點,那麼剩下的頂點中存在入度不爲零的頂點,說明有向圖中存在環。

5、樣例代碼,請參考:207. 課程表(拓撲排序)
 

 

 

四、最小生成樹(minimum spanning tree , MST)

方法1: Kruskal算法

1、先了解一下Kruskal算法的步驟:

(1)設一個有n個頂點的連通網絡爲G(V,E),將所有的邊按照權值從小到大排序。

(2)當在G中選擇一條具有最小權值的邊時,若該邊的兩個頂點落在不同的連通分量上,則將此邊加入到T中;否則,即這條邊的兩個頂點落在同一個連通分量上,會形成環,則將此邊捨去,重新選擇下一條權值最小的邊;如何判斷兩個頂點是否落在同一個聯通分量上,採用並查集來解決。

(3)如此重複下去,直到所有頂點在同一個連通分量上爲止。T就是最小生成樹。如果最後T中,不能包含所有頂點,那麼就沒有辦法構成最小生成樹。

2、Kruskal算法=一個排序+並查集

3、樣例代碼,請參考:1135. 最低成本聯通所有城市(最小生成樹)

 

方法2: prim算法

1、先了解一下Prim算法的步驟:

(1)設一個有n個頂點的連通網絡爲G(V,E), T(U, TE)是最小生成樹。V中存G的頂點,E中存G的邊。U中存T的頂點,TE中存T的邊。開始時,V中是全部頂點。U和TE都是空的。

(2)第一次先從V中隨便取一個頂點加入到U中。

(3)然後從那些其一個端點已經在U中,另一個端點在U外的所有邊中找一條最短的邊。並把該邊和頂點分別併入TE和U中。如此進行下去,每次往生成樹裏併入一個頂點和一條邊,直到n-1次之後,把所有n個頂點都併入U中,此時U=V,T是最小生成樹。如果最後T中,不能包含所有頂點,那麼就沒有辦法構成最小生成樹。

2、樣例代碼,請參考:1135. 最低成本聯通所有城市(最小生成樹)

 

 

五、最短路徑(shortest path

Dijkstra算法(單源最短路徑算法):

1、先了解一下Dijkstra算法的步驟:

(1)設一個有n個頂點的連通網絡爲G,  頂點集合U和T。最開始的時候,U中存G的全部頂點以及源點到這些頂點的路徑長度:源點到自身的路徑長度是0,源點到不相連的頂點,長度是無窮大。T爲空。

(2)每次去U中找出路徑最小的頂點uu,在U中刪掉uu,並且將uu插入到S中。

(3)在U中遍歷從uu出發能到達的所有頂點v,根據U(v)=min(U(v), S(uu)+W[uu,v]),其中W[uu,v])表示uu到v的路徑長度,更新一波U(v)的長度。

(4)重複過程(2)-(3),所有頂點都加入了S中。

2、樣例代碼,請參考:743. 網絡延遲時間(最短路徑)

 

Prim算法和Dijkstra算法的對比:

1、相同點:都是基於貪心的思想,都是一開始兩個頂點集合A和B,A爲空,B爲全部頂點,都是從B中選一個加入到A中,直到全部頂點加入完成。

2、不同點

(1)Prim算法:每次從那些其一個端點已經在A中,另一個端點在B中的所有邊中找一條最短的邊,加入A中。

(2)Dijkstra算法:每次去B中找出路徑最小的頂點uu,加入A中。

還多一個步驟:要根據uu更新一波B中的最短路徑長度。在B中遍歷從uu出發能到達的所有頂點v,根據B(v)=min(A(v), A(uu)+W[uu,v]),其中W[uu,v])表示uu到v的路徑長度,更新一波B(v)的長度。

 

 

六、關鍵路徑法(Critical Path Method, CPM)

1、先了解一下CPM的步驟,核心就是5個for 循環

Ev[i]表示事件i的最早出現時間,E[i]表示活動i的最早出現時間,Lv[i]表示事件i的最遲出現時間,L[i]表示活動i的最遲出現時間。

以j頂點指向k頂點爲例:

(1)從源點開始向匯點遞推,根據Ev[k]=max(Ev[j]+w[j,k]),求出Ev數組其中的最大值Ev[n]是匯點的最早開始時間。

(2)因爲匯點就是結束點,其最遲出現時間與最早出現時間相同,即Ev[n]=Lv[n]。將(1)中排好序的事件,從匯點開始向源點遞推,根據Lv[j]=min(Lv[k]-w[j,k]),求出Lv數組

(3)活動的最早開始時間與事件的最早開始時間是一樣的,求出E數組,E=Ev.

(4)j頂點指向k頂點,中間經歷活動aj, 根據L[j]=Lv[k]-(活動j所需的時間),求出L數組

(5)E[i]=L[i]的活動,就是關鍵活動,由這些活動組成的路徑就是關鍵路徑。

(6)有可能關鍵路徑不止一條,那麼這時候可以將re按照字典序排序,如果後一條路徑的起始點,與前一條路徑的結束點不一致,即x[i][0]!=x[i-1][1],刪後面一條路徑。那麼此時多一個for循環

2、樣例代碼,請參考:圖的知識點補充(AOE網絡的關鍵路徑)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章