寻找有向图中的弱连通分量

在探索图论的奥秘时,我们经常需要处理有向图。今天,让我们一起深入了解有向图中的一个重要概念:弱连通图

弱连通图

如果一个有向图 ‘G = (V, E)‘底层无向图(Underlying Undirected Graph)Ĝ 是连通的,那么我们就称这个有向图是弱连通的。

> 底层无向图是指图 Ĝ = (V, Ê),其中 Ê 代表无向边集合。它是通过将有向图 G 中的有向边去掉箭头(即忽略方向),使其变为双向边而得到的。

示例:

> !image

>

> 上面的有向图 G 是弱连通的,因为它的底层无向图 Ĝ 是连通的。

给定一个有向图,弱连通分量 (WCC) 是原图的一个子图,其中所有顶点都通过某条路径相互连接,且我们在判断连接时忽略了边的方向

> 示例:

>

> !image

>

> 在上面的有向图中,有两个弱连通分量:

>

> – [0, 1, 2, 3]

> – [4, 5]

寻找弱连通分量的算法

为了找到弱连通分量,我们可以利用寻找无向图中连通分量的算法。步骤非常直观:

  • 构建给定有向图的底层无向图。
  • 找出该无向图的所有连通分量
  • 无向图的这些连通分量,就是原有所向图的弱连通分量。

代码实现

下面是寻找弱连通分量的代码。它接受一个有向图 DG 作为输入,并返回输入图的所有弱连通分量 WCC

C++

#include 
#include 
#include 
using namespace std;

class Graph {
  public:
  int vertices;
  vector<vector > adjacencyList;

  Graph(int vertices) {
    this->vertices = vertices;
    adjacencyList.resize(vertices);
  }

  void addEdge(int u, int v) {

    // 使用 noEdge(int, int) 方法
    // 可以防止边的重复添加
    if (noEdge(u, v)) {
      adjacencyList[u].push_back(v);
    }
  }

  // 如果不存在
  // 从 u 到 v 的边,则返回 true
  bool noEdge(int u, int v) {
    for (int destination : adjacencyList[u]) {
      if (destination == v) {
        return false;
      }
    }
    return true;
  }
};

class WCC {
  private:
  Graph directedGraph;

  public:
  WCC(Graph directedGraph) : directedGraph(directedGraph) {
    this->directedGraph = directedGraph;
  }

  // 查找给定无向图的
  // 所有连通分量
  vector<vector > connectedComponents(Graph undirectedGraph) {
    vector<vector > connectedComponents;
    vector isVisited(undirectedGraph.vertices, false);

    for (int i = 0; i < undirectedGraph.vertices; i++) {
      if (!isVisited[i]) {
        vector component;
        findConnectedComponent(i, isVisited, component, undirectedGraph);
        connectedComponents.push_back(component);
      }
    }

    return connectedComponents;
  }

  // 使用深度优先搜索 (DFS)
  // 查找从源点开始的一个连通分量
  void findConnectedComponent(int src, vector& isVisited, vector& component, Graph undirectedGraph) {
    isVisited[src] = true;
    component.push_back(src);

    for (int v : undirectedGraph.adjacencyList[src]) {
      if (!isVisited[v]) {
        findConnectedComponent(v, isVisited, component, undirectedGraph);
      }
    }
  }

  // 步骤 1:构建
  // 底层无向图
  vector<vector > weaklyConnectedComponents() {
    Graph undirectedGraph(directedGraph.vertices);
    for (int u = 0; u < directedGraph.vertices; u++) {
      for (int v : directedGraph.adjacencyList[u]) {
        undirectedGraph.addEdge(u, v);
        undirectedGraph.addEdge(v, u);
      }
    }

    // 步骤 2:找出无向图的
    // 连通分量
    return connectedComponents(undirectedGraph);
  }
};

// 主驱动代码
int main() {
  Graph directedGraph(6);

  directedGraph.addEdge(0, 1);
  directedGraph.addEdge(0, 2);
  directedGraph.addEdge(3, 1);
  directedGraph.addEdge(3, 2);
  directedGraph.addEdge(4, 5);

  WCC wcc(directedGraph);
  vector<vector > weaklyConnectedComponents = wcc.weaklyConnectedComponents();

  int index = 1;
  for (vector component : weaklyConnectedComponents) {
    cout << "Component " << index++ << ": ";
    for (int i : component) {
      cout << i << " ";
    }
    cout << endl;
  }

  return 0;
}

Java

“`java

// 上述算法的 Java 代码实现

import java.util.ArrayList;

class Graph {

int vertices;

ArrayList<ArrayList > adjacencyList;

public Graph(int vertices)

{

this.

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。如需转载,请注明文章出处豆丁博客和来源网址。https://shluqu.cn/45818.html
点赞
0.00 平均评分 (0% 分数) - 0