給定連通無向圖,需添加最少邊使其成為邊雙連通圖(即無橋)。輸出需加邊數。
將圖的邊雙連通分量縮點,形成一棵樹(橋樹)。樹中葉子節點數為 L,則至少需添加 ceil(L/2) = (L+1)/2 條邊使其無橋。
重邊不構成橋。Tarjan 時若不處理重邊,會誤判。兩種處理:
#includeusing namespace std; const int MAXN = 200005, MAXM = 2000005; int n, m, dfn[MAXN], low[MAXN], stk[MAXN], top, idx, bccCnt; bool isBridge[MAXM]; vector G[MAXN]; struct Edge { int to, id; }; vector adj[MAXN]; void tarjan(int u, int parentEdge) { dfn[u] = low[u] = ++idx; stk[++top] = u; for (auto e : adj[u]) { int v = e.to, id = e.id; if (id == parentEdge) continue; if (!dfn[v]) { tarjan(v, id); low[u] = min(low[u], low[v]); if (low[v] > dfn[u]) isBridge[id] = true; } else low[u] = min(low[u], dfn[v]); } } void dfsBCC(int u, int bccId) { // 縮點邏輯 } int main() { while (cin >> n >> m) { // 初始化、建圖、去重 tarjan(1, -1); // 縮點、統計橋樹葉子 cout << (leaf + 1) / 2 << '\n'; } }
完整代碼較長,核心為 Tarjan 找橋 + 縮點統計葉子。