zoukankan      html  css  js  c++  java
  • hdu3844 Mining Your Own Business,无向双连接组件

    点击打开链接


    无向图的双连通分量

    #include<cstdio>
    #include<stack>
    #include<vector>
    #include<map>
    #include<algorithm>
    #include<cstring>
    #pragma comment(linker, "/STACK:102400000,102400000")
    
    using namespace std;
    typedef long long LL;
    const int maxn = 50010;
    struct Edge {
        int u, v;
        Edge(int u, int v):u(u), v(v) {}
    };
    int pre[maxn], low[maxn], bccno[maxn], iscut[maxn], bcc_cnt, dfs_clock;
    vector<int> g[maxn], bcc[maxn];
    stack<Edge> S;
    int dfs(int u, int fa)
    {
        int lowu = pre[u] = ++dfs_clock;
        int child = 0;
        for(int i = 0; i < g[u].size(); i++) {
            int v = g[u][i];
            Edge e = Edge(u, v);
            if(!pre[v]) {
                S.push(e);
                child++;
                int lowv = dfs(v, u);
                lowu = min(lowu, lowv);
                if(lowv >= pre[u]) {
                    iscut[u] = 1;
                    bcc_cnt++;
                    bcc[bcc_cnt].clear();
                    for(;;) {
                        Edge x = S.top();
                        S.pop();
                        if(bccno[x.u] != bcc_cnt) {
                            bccno[x.u] = bcc_cnt;
                            bcc[bcc_cnt].push_back(x.u);
                        }
                        if(bccno[x.v] != bcc_cnt) {
                            bccno[x.v] = bcc_cnt;
                            bcc[bcc_cnt].push_back(x.v);
                        }
                        if(x.u == u && x.v == v) break;
                    }
                }
            } else if(pre[v] < pre[u] && v!= fa) {
                S.push(e);
                lowu = min(lowu, pre[v]);
            }
        }
        if(child == 1 && fa < 0) iscut[u] = 0;
        return low[u] = lowu;
    }
    void find_bcc(int n)
    {
        memset(iscut, 0, sizeof(iscut));
        memset(pre, 0, sizeof(pre));
        memset(bccno, 0, sizeof(bccno));
    
        dfs_clock = bcc_cnt = 0;
        for(int i = 0; i < n; i++)
            if(!pre[i]) dfs(i, -1);
    }
    int kase;
    void solve(int n)
    {
        find_bcc(n);
        LL ans1 = 0, ans2 = 1;
        for(int i = 1; i <= bcc_cnt; i++) {
            int cut_cnt = 0;
            for(int j = 0; j < bcc[i].size(); j++)
                if(iscut[bcc[i][j]]) cut_cnt++;
            if(cut_cnt == 1)
                ans1++, ans2 *= (LL)(bcc[i].size() - cut_cnt);
        }
        if(bcc_cnt == 1) {
            ans1 = 2, ans2 = (LL)(n-1)*n/2;
        }
        printf("Case %d: %I64d %I64d
    ", kase, ans1, ans2);
    }
    int main(void)
    {
        int m;
        while(scanf("%d", &m), m) {
            kase++;
            for(int i = 0; i < maxn; i++)
                g[i].clear();
            int mxn = 0;
            while(m--) {
                int u, v;
                scanf("%d%d", &u, &v);
                mxn = max(mxn, max(u, v));
                u--, v--;
                g[u].push_back(v), g[v].push_back(u);
            }
            solve(mxn);
        }
        return 0;
    }
    


    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    BZOJ 1391: [Ceoi2008]order
    BZOJ 4504: K个串
    2019 年百度之星·程序设计大赛
    POJ 2398 Toy Storage (二分 叉积)
    POJ 2318 TOYS (二分 叉积)
    HDU 6697 Closest Pair of Segments (计算几何 暴力)
    HDU 6695 Welcome Party (贪心)
    HDU 6693 Valentine's Day (概率)
    HDU 6590 Code (判断凸包相交)
    POJ 3805 Separate Points (判断凸包相交)
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4612474.html
Copyright © 2011-2022 走看看