使用DFS计算有向图中的循环数

时间:2015-10-27 14:49:46

标签: algorithm graph cycle depth-first-search directed-graph

我想计算有向图中可用的定向循环总数(仅需要计数)。

您可以假设图形作为邻接矩阵给出。

我知道DFS但无法为此问题制作一个有效的算法。

请使用DFS提供一些伪代码。

2 个答案:

答案 0 :(得分:0)

让我们考虑一下,我们用三种颜色着色节点。如果尚未发现该节点,则其颜色为白色。如果发现该节点但尚未发现其任何后代,则其颜色为灰色。否则它的颜色是黑色的。现在,在进行DFS的同时,如果遇到某种情况,两个灰色节点之间存在边缘,则图形具有循环。循环总数将是我们面对上述情况的总次数,即我们在两个灰色节点之间找到边缘。

答案 1 :(得分:0)

这种基于DFS的算法似乎可以工作,但是我没有证据。

此算法是从dfs修改而来的,用于拓扑排序 (https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search)。

class Solution {
  vector<Edge> edges;
  // graph[vertex_id] -> vector of index of outgoing edges from @vertex_id.
  vector<vector<int>> graph;
  vector<bool> mark;
  vector<bool> pmark;
  int cycles;

  void dfs(int node) {
    if (pmark[node]) {
      return;
    }
    if (mark[node]) {
      cycles++;
      return;
    }
    mark[node] = true;

    // Try all outgoing edges.
    for (int edge_index : graph[node]) {
      dfs(edges[edge_index].to);
    }

    pmark[node] = true;
    mark[node] = false;
  }

  int CountCycles() {
    // Build graph.
    // ...

    cycles = 0;
    mark = vector<bool>(graph.size(), false);
    pmark = vector<bool>(graph.size(), false);
    for (int i = 0; i < (int) graph.size(); i++) {
      dfs(i);
    }

    return cycles;
  }
};