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());
}
}
- 注:本系列参考玩转算法系列–图论精讲