【问题标题】:How can I find bridges in an undirected graph? [duplicate]如何在无向图中找到桥? [复制]
【发布时间】:2023-03-14 13:00:02
【问题描述】:

给定一个无向图,我怎样才能找到所有的桥?我只发现 Tarjan 的算法看起来相当复杂。

似乎应该有多个线性时间解决方案,但我找不到任何东西。

【问题讨论】:

  • Tarjan 的算法用于在 有向 图中查找强连通分量 (SCC),不知道您想如何在此处应用它(虽然不确定它是不可能的)

标签: algorithm graph undirected-graph


【解决方案1】:

Tarjan 算法是第一个在线性时间运行的无向图中的桥梁查找算法。但是存在更简单的算法,您可以查看其实现here

    private int bridges;      // number of bridges
    private int cnt;          // counter
    private int[] pre;        // pre[v] = order in which dfs examines v
    private int[] low;        // low[v] = lowest preorder of any vertex connected to v

    public Bridge(Graph G) {
        low = new int[G.V()];
        pre = new int[G.V()];
        for (int v = 0; v < G.V(); v++) low[v] = -1;
        for (int v = 0; v < G.V(); v++) pre[v] = -1;

        for (int v = 0; v < G.V(); v++)
            if (pre[v] == -1)
                dfs(G, v, v);
    }

    public int components() { return bridges + 1; }

    private void dfs(Graph G, int u, int v) {
        pre[v] = cnt++;
        low[v] = pre[v];
        for (int w : G.adj(v)) {
            if (pre[w] == -1) {
                dfs(G, v, w);
                low[v] = Math.min(low[v], low[w]);
                if (low[w] == pre[w]) {
                    StdOut.println(v + "-" + w + " is a bridge");
                    bridges++;
                }
            }

            // update low number - ignore reverse of edge leading to v
            else if (w != u)
                low[v] = Math.min(low[v], pre[w]);
        }
    }

该算法通过维护 2 个数组 pre 和 low 来完成这项工作。 pre 保存节点的前序遍历编号。所以 pre[0] = 2 意味着在第 3 次 dfs 调用中发现了顶点 0。并且 low[u] 保存从 u 可到达的任何顶点的最小预序数。

该算法在边缘 u--v 中检测到桥,其中 u 在前序编号中排在第一位,low[v]==pre[v]。这是因为如果我们移除 u--v 之间的边,v 就无法到达 u 之前的任何顶点。因此,删除边缘会将图拆分为 2 个单独的图。

如需更详细的解释,您还可以查看this answer

【讨论】:

  • 您好 Nikunj,我只是想知道您为什么将这个称为 Tarjan 算法?尽管您发布的算法与原始 Tarjan 共享相同的 lowpre 数组,但 Tarjan 用于在有向图中查找 SCC。
  • 嘿,我只是想知道这个 Tarjan 的寻桥算法是否有 O(V) 的时间复杂度?因为,虽然我找不到算法,但没有被告知我需要在俄罗斯,据我所知,算法是 O(V) 或者有些人只是说线性时间......但这看起来不像.. 所以这不是真正的算法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-07
  • 1970-01-01
  • 1970-01-01
  • 2020-04-11
  • 1970-01-01
  • 1970-01-01
  • 2012-12-31
相关资源
最近更新 更多