在有向图中查找弱连通分量
弱连通图:
如果底层无向图Ĝ是连通的,则有向图' G = (V, E)'是弱连通的。
The underlying undirected graph is the graph Ĝ = (V, Ê) where Ê represents the set of undirected edges that is obtained by removing the arrowheads from the directed edges and making them bidirectional in G.
例子:
The directed graph G above is weakly connected since its underlying undirected graph Ĝ is connected.
弱连接组件:
给定一个有向图,弱连通分量 (WCC)是原始图的子图,其中所有顶点通过某种路径相互连接,忽略边的方向。
Example:
In the above directed graph, there are two weakly connected components:
- [0, 1, 2, 3]
- [4, 5]
查找弱连通分量的算法:
它使用该算法来查找无向图的连通分量。
- 构造给定有向图的底层无向图。
- 找出无向图的所有连通分量。
- 无向图的连通分量将是有向图的弱连通分量。
执行:
下面是Weakly Connected Component的代码,它以一个有向图DG为输入,返回输入图的所有弱连接分量WCC 。
Java
// Java Code for the above algorithm
import java.util.ArrayList;
class Graph {
int vertices;
ArrayList > adjacencyList;
public Graph(int vertices)
{
this.vertices = vertices;
adjacencyList = new ArrayList<>(vertices);
for (int i = 0; i < this.vertices; i++)
adjacencyList.add(new ArrayList<>());
}
public void addEdge(int u, int v)
{
// Use of noEdge(int, int)
// prevents duplication of edges
if (noEdge(u, v))
adjacencyList.get(u).add(v);
}
// Returns true if there does NOT exist
// any edge from u to v
boolean noEdge(int u, int v)
{
for (int destination : adjacencyList.get(u))
if (destination == v)
return false;
return true;
}
}
class WCC {
private final Graph directedGraph;
public WCC(Graph directedGraph)
{
this.directedGraph = directedGraph;
}
// Finds all the connected components
// of the given undirected graph
private ArrayList >
connectedComponents(Graph undirectedGraph)
{
ArrayList > connectedComponents
= new ArrayList<>();
boolean[] isVisited
= new boolean[undirectedGraph.vertices];
for (int i = 0; i < undirectedGraph.vertices; i++) {
if (!isVisited[i]) {
ArrayList component
= new ArrayList<>();
findConnectedComponent(i, isVisited,
component,
undirectedGraph);
connectedComponents.add(component);
}
}
return connectedComponents;
}
// Finds a connected component
// starting from source using DFS
private void
findConnectedComponent(int src, boolean[] isVisited,
ArrayList component,
Graph undirectedGraph)
{
isVisited[src] = true;
component.add(src);
for (int v :
undirectedGraph.adjacencyList.get(src))
if (!isVisited[v])
findConnectedComponent(v, isVisited,
component,
undirectedGraph);
}
public ArrayList >
weaklyConnectedComponents()
{
// Step 1: Construct the
// underlying undirected graph
Graph undirectedGraph
= new Graph(directedGraph.vertices);
for (int u = 0; u < directedGraph.vertices; u++) {
for (int v :
directedGraph.adjacencyList.get(u)) {
undirectedGraph.addEdge(u, v);
undirectedGraph.addEdge(v, u);
}
}
// Step 2: Find the connected components
// of the undirected graph
return connectedComponents(undirectedGraph);
}
}
public class WCCDemo {
// Driver Code
public static void main(String[] args)
{
Graph directedGraph = new Graph(6);
directedGraph.addEdge(0, 1);
directedGraph.addEdge(0, 2);
directedGraph.addEdge(3, 1);
directedGraph.addEdge(3, 2);
directedGraph.addEdge(4, 5);
ArrayList >
weaklyConnectedComponents
= new WCC(directedGraph)
.weaklyConnectedComponents();
int index = 1;
for (ArrayList component :
weaklyConnectedComponents) {
System.out.print("Component "
+ index++ + ": ");
for (Integer i : component)
System.out.print(i + " ");
System.out.println();
}
}
}
输出
Component 1: 0 1 3 2
Component 2: 4 5
时间复杂度: O(V+E)