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

POJ1144 Network(求割点)

2018年12月24日 ⁄ 综合 ⁄ 共 1087字 ⁄ 字号 评论关闭

http://poj.org/problem?id=1144

裸的求割点。


u是割点的条件:u是根且有大于一个的儿子,或者u不是根,且u有一个儿子v使得low[v]>=dfn[u]。


code:

#include <stdio.h>
#include <string.h>

const int maxn = 100 + 5;
int edge[maxn][maxn];
int bridge[maxn][maxn], cut[maxn];
int low[maxn], dfn[maxn], vis[maxn];
int root, rt_son;

void cut_bridge(int cur, int father, int dep, int n) {
//注意:对于每个连通块取一个点x调用cut_bridge(x,-1,0,n),其中n为点数。
    vis[cur] = 1;
    dfn[cur] = low[cur] = dep;
    for(int i=1; i<=n; ++i) if(edge[cur][i]) {
            if(i !=father && 1 == vis[i]) {
                if(dfn[i] < low[cur])
                    low[cur] = dfn[i];
            }
            if(0 == vis[i]) {
                cut_bridge(i, cur, dep+1, n);
                if(cur==root)  rt_son++;
                if(low[i] <low[cur]) low[cur] = low[i];
                if((father !=-1&&low[i]>=dfn[cur]))
                    cut[cur] = true;
                if(low[i]>dfn[cur]) {
                    bridge[cur][i] = bridge[i][cur] = true;
                }
            }
        }
    vis[cur] = 2;
}

int main() {
    int n, i, j, ans;
    char ch;
    while(scanf("%d",&n),n) {
        memset(edge, 0, sizeof edge );
        memset(dfn, 0, sizeof dfn );
        memset(bridge, 0, sizeof bridge );
        memset(cut, 0, sizeof cut );
        memset(vis, 0, sizeof vis );
        while(scanf("%d",&i),i) {
            while( (ch=getchar())!='\n' ) {
                scanf("%d",&j);
                edge[i][j] = edge[j][i] = 1;
            }
        }
        root = 1, rt_son = 0;
        cut_bridge(root, -1, 0, n);
        ans = 0;
        if(rt_son>1) ans++;
        for(i=1; i<=n; ++i)
            if(cut[i])
                ans++;
        printf("%d\n",ans);
    }
    return 0;
}

抱歉!评论已关闭.