【发布时间】:2016-01-27 01:13:21
【问题描述】:
我想计算有向图中可用的有向循环总数(只需要计数)。
您可以假设图形作为邻接矩阵给出。
我知道DFS,但无法为这个问题制定一个可行的算法。
请提供一些使用DFS的伪代码。
【问题讨论】:
-
DFS 不是只适用于无环图吗...?否则,您将永远继续潜水和潜水。
标签: algorithm graph cycle depth-first-search directed-graph
我想计算有向图中可用的有向循环总数(只需要计数)。
您可以假设图形作为邻接矩阵给出。
我知道DFS,但无法为这个问题制定一个可行的算法。
请提供一些使用DFS的伪代码。
【问题讨论】:
标签: algorithm graph cycle depth-first-search directed-graph
让我们考虑一下,我们用三种颜色为节点着色。如果节点尚未被发现,则其颜色为白色。如果节点被发现但其任何后代尚未被发现,则其颜色为灰色。否则它的颜色是黑色的。现在,在进行 DFS 时,如果我们遇到这样一种情况,两个灰色节点之间有一条边,那么图就有了循环。循环的总数将是我们面对上述情况的总次数,即我们在两个灰色节点之间找到一条边。
【讨论】:
这个基于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;
}
};
【讨论】: