图论.连通性专题
开一个关于图的连通性的专题,内容包括:
- 无向图的割点、桥、双连通分量
- 有向图的强连通分量
- 最大团
- 极大团
- 全局最小割
- 最短路相关
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
\begin{aligned}
v.low = \min
\begin{cases}
v.d, \\
w.d : \text{\((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 \(v\in 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 \(v\in 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, v\in 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;
}
};