现在的位置: 首页 > 综合 > 正文

hdu3844 Mining Your Own Business,无向图的双连通分量

2018年12月23日 ⁄ 综合 ⁄ 共 1608字 ⁄ 字号 评论关闭

点击打开链接


无向图的双连通分量

#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\n", 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;
}

抱歉!评论已关闭.