1. 圖的環檢測
無向圖有環:
- 當前點的鄰接節點已經被訪問過
- 被訪問過的鄰接節點不是當前節點的上個訪問
import java.util.ArrayList;
import java.util.Collections;
public class CycleDetection {
private Graph G;
private boolean[] visited;
private boolean hasCycle = false;
CycleDetection(Graph G) {
this.G = G;
visited = new boolean[G.V()];
//解決非連通圖的遍歷問題
for (int v = 0; v < G.V(); v++) {
if(!visited[v])
if(dfs(v, v)){
hasCycle = true;
break;
}
}
//dfs(s, s);
}
//當前節點v出發是否有環
private boolean dfs(int v, int parent) {
visited[v] = true;
for (int w : G.adj(v)) {
if (!visited[w])
if(dfs(w, v))
return true;
else if(w != parent)
return true;
}
return false;
}
public boolean hasCycle(){
return hasCycle;
}
public static void main(String[] args) {
Graph g = new Graph("g_4.txt");
CycleDetection cycleDetection = new CycleDetection(g);
System.out.println(cycleDetection.hasCycle());
}
}
- 判斷一張圖是否是一棵樹
- 圖中沒環
- 圖聯通
2. 二分圖檢測
對於非聯通圖,只要每個連通分量是一個二分圖,整體就一定是一個二分圖
import java.util.ArrayList;
public class BipartitionDetection {
private Graph G;
private boolean[] visited;
private int[] colors; //colors[i]:節點i的顏色:0、1
private boolean isBipartite = true;
public BipartitionDetection(Graph G){
this.G = G;
visited = new boolean[G.V()];
colors = new int[G.V()];
for(int i = 0; i < G.V(); i ++)
colors[i] = -1;
for(int v = 0; v < G.V(); v ++)
if(!visited[v])
if(!dfs(v, 0)){
isBipartite = false;
break;
}
}
private boolean dfs(int v, int color){
visited[v] = true;
colors[v] = color; //節點v染成color
for(int w: G.adj(v))
if(!visited[w]){
if(!dfs(w, 1 - color)) return false;
}
else if(colors[w] == colors[v]) //當前節點與訪問過的鄰接節點顏色一致
return false;
return true;
}
public boolean isBipartite(){
return isBipartite;
}
public static void main(String[] args){
Graph g = new Graph("g_4_1.txt");
BipartitionDetection bipartitionDetection = new BipartitionDetection(g);
System.out.println(bipartitionDetection.isBipartite());
}
}
- 注:本系列參考玩轉算法系列–圖論精講