在移除后使得图形不连通的边称为 '桥梁'。您可以通过对整个图进行单次深度优先搜索,在O(|V|+|E|)中找到它们。相关算法找到所有 '关节点'(如果删除,则使图形断开连接的节点)。连接两个关节点之间的任何边都是一个桥梁(您可以在所有边的第二遍遍历中测试它)。
void dfs_art_i(graph *g, int v, int *r_p, int *r_v, int *r_a, int *r_ap, int *n_v) {
int i;
r_v[v] = *n_v;
r_a[v] = *n_v;
(*n_v) ++;
for (i=0; i<g->vertices[v].n_edges; i++) {
int w = g->vertices[v].edges[i].target;
if (r_v[w] == -1) {
r_p[w] = v;
dfs_art_i(g, w, r_p, r_v, r_a, r_ap, n_v);
if (r_a[w] >= r_v[v]) {
r_ap[i] = 1;
}
if (r_a[w] < r_a[v]) {
r_a[v] = r_a[w];
}
}
else {
if (r_v[w] < r_a[v]) {
r_a[v] = r_v[w];
}
}
}
}
int dfs_art(graph *g, int root, int *r_p, int *r_v, int *r_a, int *r_ap) {
int i, n_visited = 0, n_root_children = 0;
for (i=0; i<g->n_vertices; i++) {
r_p[i] = r_v[i] = r_a[i] = -1;
r_ap[i] = 0;
}
dfs_art_i(g, root, r_p, r_v, r_a, r_ap, &n_visitados);
for (i=0; i<g->n_vertices; i++) {
if (r_p[i] == root) {
n_root_children ++;
}
}
r_ap[root] = n_root_children > 1 ? 1 : 0;
return 1;
}