CF1000E We Need More Bosses

传送门

题意

image

题解

显然,在边双中,$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;
}
posted @ 2018-08-05 18:31  MCH__ds  阅读(351)  评论(0编辑  收藏  举报