zoukankan      html  css  js  c++  java
  • Network POJ

    题面

    传送门

    题解

    缩点边双没跑了, 主要是算答案

    采用靠并查集爬树的思想

    int h[N], to[M << 2], ne[M << 2], tot;
    void add(int u, int v) { ne[++tot] = h[u]; to[h[u] = tot] = v; }
    
    int dfn[N], df, st[N], low[N];
    int c[N], ecnt, top;
    void tarjan(int x, int bian) {
        dfn[st[++top] = x] = low[x] = ++df;
        for (int i = h[x]; i; i = ne[i]) {
            int y = to[i];
            if (!dfn[y]) tarjan(y, i), umin(low[x], low[y]);
            else if (i != (bian ^ 1)) umin(low[x], dfn[y]);
        }
        if (low[x] == dfn[x]) {
            ++ecnt; int y;
            do c[y = st[top--]] = ecnt; while (y != x);
        }
    }
    
    int f[N], dep[N], ans, pre[N];
    
    int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
    
    void dfs(int x, int fa) {
        pre[x] = fa; dep[x] = dep[fa] + 1;
        for (int i = h[x]; i; i = ne[i]) {
            int y = to[i];
            if (y == fa) continue;
            dfs(y, x);
        }
    }
    
    void lca(int x, int y) {
        x = find(x), y = find(y);
        while (x != y) {
            if (dep[x] > dep[y]) { st[++top] = x; x = find(pre[x]); }
            else { st[++top] = y; y = find(pre[y]); }
            --ans;
        }
        while (top) f[st[top--]] = x;
    }
    
    int main() {
        IOS; int cas = 0;
        while (cin >> n >> m, n && m) {
            cout << "Case " << ++cas << ":
    ";
            df = ecnt = ans = 0; tot = 1;
            rep(i, 1, n) h[i] = dfn[i] = 0;
            rep(i, 1, m) {
                int u, v; cin >> u >> v;
                add(u, v); add(v, u);
            }
            tarjan(1, -1);
            rep(i, 1, ecnt) h[i] = 0, f[i] = i;
            for (int i = tot; i >= 2; i -= 2) {
                int u = c[to[i ^ 1]], v = c[to[i]];
                if (u == v) continue;
                add(u, v); add(v, u); ++ans;
            }
            dfs(1, 0);
            for (cin >> _; _; --_) {
                int u, v; cin >> u >> v; lca(c[u], c[v]);
                cout << ans << '
    ';
            } cout << '
    ';
        }
        return 0;
    }
    
  • 相关阅读:
    SQL(4)— Date、order by
    步入三十(二)
    【js】特殊字符转义
    【ionic】项目中$ionicModal简单用法
    【ionic】常见问题处理
    【js】视频截图
    实现笔记本拔除电源后修改屏幕缩放比例
    激活 公众号java
    【Golang】基于beego/orm实现相同表结构不同表名的分表方法实现
    .Net Cors 跨域配置域名通配符
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/14111130.html
Copyright © 2011-2022 走看看