(轉)判斷一個圖是否有環 無向圖 有向圖


無向圖:

法1:

  • 如果存在回路,則必存在一個子圖,是一個環路。環路中所有頂點的度>=2。   
  • n算法:   
  •      第一步:刪除所有度<=1的頂點及相關的邊,並將另外與這些邊相關的其它頂點的度減一。   
  •      第二步:將度數變為1的頂點排入隊列,並從該隊列中取出一個頂點重復步驟一。   
  •      如果最后還有未刪除頂點,則存在環,否則沒有環。   
  • n算法分析:   
  •      由於有m條邊,n個頂點。如果m>=n,則根據圖論知識可直接判斷存在環路。   
  •     (證明:如果沒有環路,則該圖必然是k棵樹 k>=1。根據樹的性質,邊的數目m = n-k。k>=1,所以:m<n)   
  •      如果m<n 則按照上面的算法每刪除一個度為0的頂點操作一次(最多n次),或每刪除一個度為1的頂點(同時刪一條邊)操作一次(最多m次)。這兩種操作的總數不會超過m+n。由於m<n,所以算法復雜度為O(n) 

 

另:

該方法,算法復雜度不止O(V),首先初始時刻統計所有頂點的度的時候,復雜度為(V + E),即使在后來的循環中E>=V,這樣算法的復雜度也只能為O(V + E)。其次,在每次循環時,刪除度為1的頂點,那么就必須將與這個頂點相連的點的度減一,並且執行delete node from list[list[node]],這里查找的復雜度為list[list[node]]的長度,只有這樣才能保證當degree[i]=1時,list[i]里面只有一個點。這樣最差的復雜度就為O(EV)了。

法2:

DFS搜索圖,圖中的邊只可能是樹邊或反向邊,一旦發現反向邊,則表明存在環。該算法的復雜度為O(V)。

 

有向圖:

主要有深度優先和拓撲排序2中方法

 1、拓撲排序,如果能夠用拓撲排序完成對圖中所有節點的排序的話,就說明這個圖中沒有環,而如果不能完成,則說明有環。

    2、可以用Strongly Connected Components來做,我們可以回憶一下強連通子圖的概念,就是說對於一個圖的某個子圖,該子圖中的任意u->v,必有v->u,則這是一個強連通子圖。這個限定正好是環的概念。所以我想,通過尋找圖的強連通子圖的方法應該可以找出一個圖中到底有沒有環、有幾個環。

    3、就是用一個改進的DFS

    剛看到這個問題的時候,我想單純用DFS就可以解決問題了。但細想一下,是不能夠的。如果題目給出的是一個無向圖,那么OK,DFS是可以解決的。但無向圖得不出正確結果的。比如:A->B,A->C->B,我們用DFS來處理這個圖,我們會得出它有環,但其實沒有。

    我們可以對DFS稍加變化,來解決這個問題。解決的方法如下:

    圖中的一個節點,根據其C[N]的值,有三種狀態:

    0,此節點沒有被訪問過

    -1,被訪問過至少1次,其后代節點正在被訪問中

    1,其后代節點都被訪問過。

    按照這樣的假設,當按照DFS進行搜索時,碰到一個節點時有三種可能:

    1、如果C[V]=0,這是一個新的節點,不做處理

    2、如果C[V]=-1,說明是在訪問該節點的后代的過程中訪問到該節點本身,則圖中有環。

    3、如果C[V]=1,類似於2的推導,沒有環。    在程序中加上一些特殊的處理,即可以找出圖中有幾個環,並記錄每個環的路徑

 

 c - 頂點顏色表 c[u]
    0 白色,未被訪問過的節點標白色
    -1 灰色,已經被訪問過一次的節點標灰色
    1 黑色,當該節點的所有后代都被訪問過標黑色

反向邊:
   如果第一次訪問(u,v)時v為灰色,則(u,v)為反向邊。在對圖的深度優先搜索中沒有發現
   反向邊,則該圖沒有回路。

 

 

總結:對於無向圖和有向圖,都可以采用深度優先搜索的方式,判斷某個節點的所有相鄰接的節點是否被訪問時,如果C[N]為-1,則表示存在包含這兩個節點的環。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM