❶ 中國郵遞員問題 強連通圖 如何找最優解
是離散數學中圖論的一題,由中國組合數學家管梅谷教授提出。
題目:郵遞員要穿過城市的每一條路至少一次,怎樣行走走過的路程最短?
如果你有學過離散數學,那請看下面的解
首先,這不是一個NPC問題,即存在多項式復雜度的演算法
演算法過程:先求出度為奇數的點,用匹配演算法算出這些點間的連接方式,然後再用歐拉路徑演算法求解。
❷ 請問數據結構中圖的強連通分量是什麼能具體解釋一下嗎
強連通分量是有向圖中的概念,就是每一個頂點到其它點都由路徑,注意有方向。
step1:對原圖G進行深度優先遍歷,記錄每個節點的離開時間。
step2:選擇具有最晚離開時間的頂點,對反圖GT進行遍歷,刪除能夠遍歷到的頂點,這些頂點構成一個強連通分量。
step3:如果還有頂點沒有刪除,繼續step2,否則演算法結束。
如果把求出來的每個強連通分量收縮成一個點,並且用求出每個強連通分量的順序來標記收縮後的節點,那麼這個順序其實就是強連通分量收縮成點後形成的有向無環圖的拓撲序列。
(2)強連通圖演算法擴展閱讀:
Kosaraju演算法的第二次深搜隱藏了一個拓撲性質,而Tarjan演算法和Gabow演算法省略了第二次深搜,所以,它們不具有拓撲性質。
Tarjan演算法用堆棧和標記,Gabow用兩個堆棧(其中一個堆棧的實質是代替了Tarjan演算法的標記部分)來代替Kosaraju演算法的第二次深搜,所以只用一次深搜,效率比Kosaraju演算法要高。
在這個節點訪問之前,能夠構成強連通分量的那些節點已經被彈出了,這個對Tarjan演算法有了解的都應該清楚,那麼Tarjan演算法中的判斷根我們用什麼來代替呢?想想,其實就是看看第二個堆棧的頂元素是不是當前頂點就可以了。
❸ 強連通分量(Kosaraju演算法)
{ //判斷各個強連通分量是否為出度為0的分量 for(int t = 0; t
❹ [圖論]DFS求有向圖強連通分量演算法的正確性
詳情請見《數據結構》第三版
❺ 請問如何求(有向/無向)圖的強連通分量,還有,基礎一點,怎麼求有幾個連通圖啊
尋找強烈連接組件的演算法有Tarjan的,kosaraju兩種演算法
相比Tarjan的寫了相對簡單Kosaraju的太麻煩了
但認為它是相對簡單
Kosaraju其他要求強烈連接組件如果有,估計需要更先進的數據結構演算法的演算法
建議或學校根據Tarjan的,因為他可以幫助你做很多事情,如尋求橋切點減少環,但也寫一些簡單的 BR p>連通圖的方法可以直接DFS每個DFS一個點把它記錄已經達到了,然後繼續向下搜索,每次DFS可以計算出一個連通圖
附加Tarjan的代碼</ VAR
下,頭,點:數組[1 .. 1000] Longint型;
時間,TOT,I,J,N,M,X,Y,T:Longint型;
V:ARRAY [1 .. 10000]位元組;
F,Z,Q:ARRAY [1 .. 1000] Longint型;
低,原因:[1陣列。 0.10000] Longint型;
函數min(X,Y:Longint型):Longint型;
開始
如果x <y,那麼退出(X)其他出口(Y);
結束;
程序地址(X,Y:Longint型);
開始
公司(TOT);
下一個[合計]:=頭[X]
頭[X]:= TOT
點[合計]:= Y;
結束;
程序DFS(X:Longint型);
VAR
I,J: Longint型;
公司(時間)開始;
低[X]:=時間;
原因[X]:=時間;
V [X]:= 1
公司(T);
Z [T]:= X;
:=頭[X]
而J > 0
開始
V [點[J] = 0,那麼(DFS點[J]);
如果v [點[J] <2低[X]:= MIN(下限[點[ J],低[X]);
J:=未來[J];
結束;
低[X] =原因[X],然後
開始...... / a>公司(TOT);
而Z [T +1] > X你
開始
公司(Q [合計]);
F [Z [T]] := TOT
V [Z [T]]:= 2;
十二月(T);
結束;
結束;
結束;
開始
我:= 1米做
開始
readln(X,Y);
載入(,Y readln(N,M))
結束;
TOT:= 0;時間:= 0;
我:= 1到n做
V [I] = 0,則DFS(I);
/ / writeln(TOT);
我:= 1到n做
如果q [F [I]]> 1,則writeln('T')其他writeln('F ');
結束。
❻ 強連通分量的Kosaraju演算法思路
這個演算法可以說是最容易理解,最通用的演算法,其比較關鍵的部分是同時應用了原圖G和反圖GT。步驟1:先用對原圖G進行深搜形成森林(樹),步驟2:然後任選一棵樹對其進行深搜(注意這次深搜節點A能往子節點B走的要求是EAB存在於反圖GT),能遍歷到的頂點就是一個強連通分量。餘下部分和原來的森林一起組成一個新的森林,繼續步驟2直到
沒有頂點為止。
改進思路:
當然,基本思路實現起來是比較麻煩的(因為步驟2每次對一棵樹進行深搜時,可能深搜到其他樹上去,這是不允許的,強連通分量只能存在單棵樹中(由開篇第一句話可知)),我們當然不這么做,我們可以巧妙的選擇第二深搜選擇的樹的順序,使其不可能深搜到其他樹上去。想像一下,如果步驟2是從森林裡選擇樹,那麼哪個樹是不連通(對於GT來說)到其他樹上的呢?就是最後遍歷出來的樹,它的根節點在步驟1的遍歷中離開時間最晚,而且可知它也是該樹中離開時間最晚的那個節點。這給我們提供了很好的選擇,在第一次深搜遍歷時,記錄時間i離開的頂點j,即numb[i]=j。那麼,我們每次只需找到沒有找過的頂點中具有最晚離開時間的頂點直接深搜(對於GT來說)就可以了。每次深搜都得到一個強連通分量。
隱藏性質:
分析到這里,我們已經知道怎麼求強連通分量了。但是,大家有沒有注意到我們在第二次深搜選擇樹的順序有一個特點呢?如果在看上述思路的時候,你的腦子在思考,相信你已經知道了!!!它就是:如果我們把求出來的每個強連通分量收縮成一個點,並且用求出每個強連通分量的順序來標記收縮後的節點,那麼這個順序其實就是強連通分量收縮成點後形成的有向無環圖的拓撲序列。為什麼呢?首先,應該明確搜索後的圖一定是有向無環圖呢?廢話,如果還有環,那麼環上的頂點對應的所有原來圖上的頂點構成一個強連通分量,而不是構成環上那麼多點對應的獨自的強連通分量了。然後就是為什麼是拓撲序列,我們在改進分析的時候,不是先選的樹不會連通到其他樹上(對於反圖GT來說),也就是後選的樹沒有連通到先選的樹,也即先出現的強連通分量收縮的點只能指向後出現的強連通分量收縮的點。那麼拓撲序列不是理所當然的嗎?這就是Kosaraju演算法的一個隱藏性質。
Kosaraju_Algorithm:
step1:對原圖G進行深度優先遍歷,記錄每個節點的離開時間。
step2:選擇具有最晚離開時間的頂點,對反圖GT進行遍歷,刪除能夠遍歷到的頂點,這些頂點構成一個強連通分量。
step3:如果還有頂點沒有刪除,繼續step2,否則演算法結束。
C++
#include
#include
using namespace std;const int MAXN=110;int n;bool flag[MAXN];//訪問標志數組int belg[MAXN];//存儲強連通分量,其中belg[i]表示頂點i屬於第belg[i]個強連通分量int numb[MAXN];//結束時間標記,其中numb[i]表示離開時間為i的頂點AdjTableadj[MAXN],radj[MAXN];//鄰接表,逆鄰接表//用於第一次深搜,求得numb[1..n]的值voidVisitOne(intcur,int&sig){flag[cur]=true;for(inti=1;i<=adj[cur][0];++i){if(false==flag[adj[cur][i]]){VisitOne(adj[cur][i],sig);}}numb[++sig]=cur;}//用於第二次深搜,求得belg[1..n]的值voidVisitTwo(intcur,intsig){flag[cur]=true;belg[cur]=sig;for(inti=1;i<=radj[cur][0];++i){if(false==flag[radj[cur][i]]){VisitTwo(radj[cur][i],sig);}}}//Kosaraju演算法,返回為強連通分量個數intKosaraju_StronglyConnectedComponent(){inti,sig;//第一次深搜memset(flag+1,0,sizeof(bool)*n);for(sig=0,i=1;i<=n;++i){if(false==flag[i]){VisitOne(i,sig);}}//第二次深搜memset(flag+1,0,sizeof(bool)*n);for(sig=0,i=n;i>0;--i){if(false==flag[numb[i]]){VisitTwo(numb[i],++sig);}}returnsig;}
❼ 怎麼用c語言和數據結構來編寫一個判斷有向圖是否為強連通圖的演算法
強連通圖表明任意兩點之間可以互相到達。
方案1:判斷結點A可以到達的點的方法如下:
首先SA = {A};
while 1
取SA中任意沒有被去過的點x,根據以x為起點的有向線段,判斷x可以直接到達的點,然後這些點加入SA;
如此循環,直到SA中的點的個數沒有變化了
end
這樣得到的集合SA是所有A可以到達的點的一個集合。
判斷SA 是否等於S,若不等於S,表明不是強連通。
如此循環,求出所有S中的點的能夠到達的點集。如果所有的點集都等於S表明強連通圖。
方案2:可以優化1