有向图强连通分量:在有向图G中,如果两个顶点vi,vj间有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量。
Kosaraju算法可以用来计算有向图的强连通分量。
Kosaraju算法的实现过程:
除了下面代码中标出的两行区别,Kosaraju算法的实现和求无向图的连通性问题的实现几乎完全相同。Kosaraju算法实现简单但难以理解。在知乎上看到一个对Kosaraju算法的浅显易懂的解释,可以用来帮助理解该算法的原理:https://www.zhihu.com/question/58926821/answer/163724688
实现:
public class KosarajuSharirSCC {
private boolean[] marked; // 已访问过的顶点
private int[] id; // 强连通分量的标识符
private int count; //强连通分量的数量
public KosarajuSharirSCC(Digraph G) {
marked = new boolean[G.V()];
id = new int[G.V()];
DepthFirstOrder dfs = new DepthFirstOrder(G.reverse());//区别
for (int v : dfs.reversePost()) {//区别
if (!marked[v]) {
dfs(G, v);
count++;
}
}
}
private void dfs(Digraph G, int v) {
marked[v] = true;
id[v] = count;
for (int w : G.adj(v)) {
if (!marked[w]) dfs(G, w);
}
}
public int count() { return count; }
public boolean stronglyConnected(int v, int w) { return id[v] == id[w]; }
}