CF1000E We Need More Bosses
传送门
题意
题解
显然,在边双中,$s$ 到 $t$之间不存在必须经过的边。
因此,我们缩点,然后求树的直径就好了。
附上代码:
// By hanghang0702, contest: Educational Codeforces Round 46 (Rated for Div. 2), problem: (E) We Need More Bosses, Accepted, # #include <bits/stdc++.h> using namespace std; #define down(x, y) x = min(x, y) int n, m; struct edge { int from, to, nxt, id; } edges[600005]; struct edgE { int to, nxt; } edgEs[600005]; int e0, e = 1, e2 = 1, hed[300005], hEd[300005], tim = 0, fa[300005], dfn[300005], low[300005], scc[300005], dis[300005]; stack<int> S; void addedge(int x, int y) { edges[e] = (edge){x, y, hed[x], e2}; hed[x] = e++; edges[e] = (edge){y, x, hed[y], e2++}; hed[y] = e++; } void addedgE(int x, int y) { edgEs[e] = (edgE){y, hEd[x]}; hEd[x] = e++; } void _tarjan(int x) { dfn[x] = low[x] = ++tim; S.push(x); for (int e=hed[x]; e; e=edges[e].nxt) { int y = edges[e].to; if (edges[e].id == fa[x]) continue; if (!dfn[y]) { fa[y] = edges[e].id; _tarjan(y); down(low[x], low[y]); } else down(low[x], dfn[y]); } if (dfn[x] == low[x]) { scc[x] = ++e2; while (S.top() != x) { scc[S.top()] = e2; S.pop(); } S.pop(); } } void tarjan() { _tarjan(1); for (int i = 0; i < e0; i++) { int x = edges[i].from, y = edges[i].to; if (scc[x] == scc[y]) continue; addedgE(scc[x], scc[y]); } } void dfs(int x, int fa) { for (int e=hEd[x]; e; e=edgEs[e].nxt) { int y = edgEs[e].to; if (y != fa) { dis[y] = dis[x] + 1; dfs(y, x); } } } int solve() { dfs(1, 0); int mx = 0, id = 1; for (int i=1; i<=n; i++) if (dis[i] > mx) mx = dis[i], id = i; memset(dis, 0, sizeof(dis)); dfs(id, 0); mx = 0; for (int i=1; i<=n; i++) mx = max(mx, dis[i]); return mx; } int main() { ios :: sync_with_stdio(false); cin >> n >> m; for (int i=1; i<=m; i++) { int x, y; cin >> x >> y; addedge(x, y); } e0 = e; e = 1; e2 = 0; tarjan(); cout << solve() << endl; return 0; }