1 条题解
-
1
using namespace std; const int MAXN = 5005; vector<pair<int, int>> g[MAXN]; int dfn[MAXN], low[MAXN], timer; bool isBridge[20005]; int comp[MAXN]; void tarjan(int u, int peid) { dfn[u] = low[u] = ++timer; for (auto e : g[u]) { int v = e.first, eid = e.second; if (eid == peid) continue; // 跳过同一条边的反向,重边不会误判 if (!dfn[v]) { tarjan(v, eid); low[u] = min(low[u], low[v]); if (low[v] > dfn[u]) isBridge[eid] = true; } else { low[u] = min(low[u], dfn[v]); } } } int main() { int F, R; scanf("%d %d", &F, &R); for (int i = 0; i < R; i++) { int a, b; scanf("%d %d", &a, &b); g[a].push_back({b, i}); g[b].push_back({a, i}); } for (int i = 1; i <= F; i++) if (!dfn[i]) tarjan(i, -1); // 删掉所有桥,剩下的连通块即边双连通分量 int cid = 0; for (int i = 1; i <= F; i++) { if (comp[i]) continue; cid++; queue<int> q; q.push(i); comp[i] = cid; while (!q.empty()) { int u = q.front(); q.pop(); for (auto e : g[u]) { int v = e.first, eid = e.second; if (isBridge[eid] || comp[v]) continue; comp[v] = cid; q.push(v); } } } // 桥树中度数:每条桥给其两端分量各 +1 vector<int> deg(cid + 1, 0); for (int u = 1; u <= F; u++) for (auto e : g[u]) if (isBridge[e.second]) deg[comp[u]]++; int leaves = 0; for (int i = 1; i <= cid; i++) if (deg[i] == 1) leaves++; printf("%d\n", (leaves + 1) / 2); return 0; }
信息
- ID
- 431
- 时间
- 1000ms
- 内存
- 64MiB
- 难度
- 10
- 标签
- 递交数
- 5
- 已通过
- 4
- 上传者