图论.连通性专题

开一个关于图的连通性的专题,内容包括:

  • 无向图的割点、桥、双连通分量
  • 有向图的强连通分量
  • 最大团
  • 极大团
  • 全局最小割
  • 最短路相关

Introduction to Algorithms 3rd edition, page 621,

Problem 22-2 Articulation points, bridges, and biconnected components

Let $G = (V, E)$ be a connected, undirected graph. An articulation point of $G$ is a vertex whose removal disconnects $G$. A bridge of $G$ is an edge whose removal disconnects $G$. A biconnected component of $G$ is a maximal set of edges such that any two edges in the set lie on a common simple cycle. Figure 22.10 illustrates these definitions.

We can determine articulation points, bridges, and biconnected components using depth-first search. Let $G_{pi} = (V, E_{pi})$ be a depth-first tree of $G$.
a. Prove that the root of $G_{pi}$ is an articulation point of $G$ if and only if it has at least two children in $G_{pi}$.
b. Let $v$ be a nonroot vertex of $G_{pi}$. Prove that $v$ is an articulation point of $G$ if and only if $v$ has a child $s$ such that there is no back edge from $s$ or any descendant of $s$ to a proper ancestor of $v$.
c. Let
egin{aligned}
v.low = min
egin{cases}
v.d, \
w.d : ext{$(u, w)$ is a back edge for some descendant $u$ of $v$}.
end{cases}
end{aligned}
Show how to compute $v.low$ for all vertices $vin V$ in $O(E)$ time.
d. Show how to compute all articulation points in $O(E)$ time.
e. Prove that an edge of $G$ is a bridge if and only if it does not lie on any simple cycle of $G$.
f. Show how to compute all the bridges of $G$ in $O(E)$ time.
g. Prove that the biconnected components of $G$ partition the nonbridge edges of $G$.
h. Give an $O(E)$-time algorithm to label each edge $e$ of $G$ with a positive integer $e.bcc$ such that $e.bcc = e'.bcc$ if and only if $e$ and $e'$ are in the same biconnected component.

Problem 22-3 Euler tour

An Euler tour of a strongly connected, directed graph $G = (V, E)$ is a cycle that traverses each edge of $G$ exactly once, although it may visit a vertex more than once.
a. Show that $G$ has an Euler tour if and only if in-degree($v$) = out-degree($v$) for each vertex $vin V$.
b. Describe an $O(E)$-time algorithm to find an Euler tour of $G$ if one exists. (Hint: Merge edge-disjoint-cycles.)

Problem 22.5-7

A directed graph $G = (V, E)$ is semiconnected if, for all pairs of vertices $u, vin V$, we have $u leadsto v$ or $v leadsto u$. Give an efficient algorithm to determine whether or not $G$ is semiconnected. Prove that your algorithm is correct, and analyze its running time.

求 $G$ 的强连通分量,缩点后得到一个 DAG。问题可归约为求这个 DAG 是否为 semiconnected。一个 DAG 是 semiconnected 当且仅当其中有一个生成子图是一条链,换言之,设 DAG 中有 $n$ 个节点,这些节点按拓扑序依次是 $v_1, v_2, dots, v_n$,对于每个 $i =1, 2, 3, dots, n - 1$,要有一条从 $v_i$ 到 $v_{i+1}$ 的有向边。
至于代码实现,以 Tarjan 的强连通分量算法为例,我们可以在 DFS 的过程中,对于每个点 $u$ 计算出从 $u$ 出发的边所能到达的其他强连通分量的编号的最大值。

  SCC(int n, const Graph &g,
      function<int(const Arc &e)> get_v = [](const Arc &e) { return e; })
      : n(n),
        g(g),
        get_v(move(get_v)),
        scc_id(n + 1, -1),
        scc_cnt(0) {}  // SCCs are indexed from 0
  bool dfs(int u) {
    static int time;
    static stack<int> s;
    static vector<int> low(n + 1), order(n + 1);
    static vector<bool> in_stack(n + 1);
    static vector<int> max_scc_id(n + 1, -1);
    order[u] = low[u] = ++time;
    s.push(u);
    in_stack[u] = true;

    for (auto &e : g[u]) {
      int v = get_v(e);
      if (!order[v]) {
        if (!dfs(v)) {
          return false;
        }
        low[u] = min(low[u], low[v]);
      } else if (in_stack[v]) {
        low[u] = min(low[u], order[v]);
      }
      if (!in_stack[v]) {
        max_scc_id[u] = max(max_scc_id[u], scc_id[v]);
      }
    }
    int max_scc_ID = -1;
    if (order[u] == low[u]) {
      while (true) {
        int v = s.top();
        s.pop();
        in_stack[v] = false;
        scc_id[v] = scc_cnt;
        max_scc_ID = max(max_scc_ID, max_scc_id[v]);
        if (u == v) break;
      }
      if (max_scc_ID != scc_cnt - 1) {
        return false;
      }
      ++scc_cnt;
    }
    return true;
  }
};
原文地址:https://www.cnblogs.com/Patt/p/6001434.html