日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

图论中环的判断

發布時間:2023/12/20 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图论中环的判断 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

無向圖環的判斷

  • 并查集判斷
    • 如果兩個結點父親相同,并且兩個結點之間有邊相連,則存在環
def init(); def find(int x);//必須進行路徑壓縮 def merge(int x, int y); if(find(x) == find(y) && G[x][y] != 0){ cycle = true;} else merge(x,y);
  • DFS判斷
    • dfs的過程中如果遇到已經訪問過的點,并且這個點不是自己的直接父親,那么就必然存在環
public class Cycle {private boolean[] marked;private boolean hasCycle;public Cycle(Graph G) {???????this.marked = new boolean[G.V()];this.hasCycle = false;for(int i=1; i<G.V(); i++) {if(!marked[i]) {//默認第一個結點沒有父節點dfs(G, i, -1);}}}private void dfs(Graph G, int cur, int pre) {marked[cur] = true;for(Integer nxt : G.adj(cur)) {if(!marked[nxt]) {dfs(G, nxt, cur);}else if(nxt != pre) {this.hasCycle = true;}}}public boolean hasCycle() {return this.hasCycle;}

有向圖環的判斷

  • 單純判斷
    • 在dfs的過程中,把dfs經過的結點全部保存在一個棧上(或者直接用布爾數組進行標記),然后每當經過一個結點時,判斷當前結點是否在棧上,是則有環
    • 事實上其實質就是,在dfs的過程中又遇到了已經訪問過的點,則必然存在環
  • 問題:為什么這里不需要考慮:如果該點已經被訪問過并且該點是父親結點的情況呢?無向圖中不是考慮了嗎?
    • 這里是有向圖,如果從孩子結點能有邊返回到父親結點,那么顯然這兩者之間存在環。
  • 記錄環中的結點
    • 需要用棧記錄當前路徑經過的結點,并且記錄每個結點的父親結點,也就是說記錄一下在當前路徑中,當前結點是哪一個結點來的。
    • 如果遇到了一個結點已經被訪問過并且在棧上, 那么必然存在一個有向環。從這個結點出發,一直找當前結點的父結點,記錄到結果容器里面,直到又遇到這個結點。
    • 注意這個dfs路徑記錄棧,當某一次dfs要返回的時候(此時已經確定在 這一遍dfs中無法找到環),則沿途回溯取消所有結點在棧上的標記(把布爾數組置為false)
public class DiCycle {private boolean[] marked;//記錄結點是否訪問過private int[] edgeTo;//記錄該結點的父節點private Stack<Integer> cycle;private boolean[] onStack;//記錄當前訪問路徑上的結點public DiCycle(Digraph G) {marked = new boolean[G.V()];edgeTo? = new int[G.V()];cycle = new Stack<Integer>();onStack = new boolean[G.V()];for(int i=0; i<G.V(); i++) {if(!marked[i]) {dfs(G, i);}}}private void dfs(Digraph G, int v) {// TODO Auto-generated method stubmarked[v] = true;onStack[v] = true;for(Integer w : G.adj(v)) {if(this.hasCycle()) return ;else if(!marked[w]) {edgeTo[w] = v;dfs(G , w);}else if(onStack[w]) {for(int x=v; x!=w; x=edgeTo[x]) {cycle.push(x);}cycle.push(w); cycle.push(v);}}onStack[v] = false;//回溯時取消其在棧上,相當于清空棧,便于下一次dfs???????}public void showCycle() {if(!this.hasCycle()) System.out.println("no cycle...");Stack<Integer> s = new Stack<Integer>();s = (Stack<Integer>) cycle.clone();while(!s.isEmpty()) {System.out.println(s.peek());s.pop();}}

轉載于:https://www.cnblogs.com/czsharecode/p/10709715.html

總結

以上是生活随笔為你收集整理的图论中环的判断的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。