POJ 1523 SPF 无向图求割点

来源:互联网 发布:乐唯石英石水槽 知乎 编辑:程序博客网 时间:2024/04/29 16:33

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

题意:给你一个有N个点的network,要你求图中的割点,对应每个割点给出删除该割点之后,图会变成几个不连通的子图。

思路:双连通求割点,对于第二问,其实只需要求出割点在哪几个双连通子图中出现过即可。

代码:

#include<stdio.h>#include<string.h>const int MAXN = 1010 ;int g[MAXN][MAXN],N;bool vis[MAXN] ;int dfn[MAXN] , low[MAXN] , stack[MAXN] ;int top , idx , cnt ;int bcc[MAXN][MAXN] ;void init(){    for(int i=1;i<MAXN;i++)        for(int j=1;j<MAXN;j++)            g[i][j] = 0 ;    memset(vis , 0 ,sizeof(vis));}void tarjin(int x, int pre){    dfn[x] = low[x] = ++idx ;    stack[++top] = x ;    for(int i=1;i<MAXN;i++){        if(i==pre || g[x][i]==0 || vis[i]==0)    continue ;        if( dfn[i]==-1 ){            tarjin(i,x) ;            if( low[i] < low[x])                low[x] = low[i] ;            if( low[i] >= dfn[x] ){                ++ cnt ;                int u ;                do{                    u = stack[top--] ;                    bcc[cnt][u] = 1 ;                }while( u!=i ) ;                bcc[cnt][x] = 1 ;            }        }        else if( dfn[i]<low[x])            low[x] = dfn[i] ;    }}void solve(){    idx = top = cnt = 0 ;    memset(dfn, -1, sizeof(dfn));    memset(bcc , 0 , sizeof(bcc));    for(int i=1;i<MAXN;i++){        if( vis[i] == 0)    continue ;        if( dfn[i] == -1){            tarjin(i , -1);        }    }    bool f = 1 ;    for(int i=1;i<MAXN;i++){        if( vis[i]==0 ) continue ;        int c = 0 ;        for(int j=1;j<=cnt;j++){            if( bcc[j][i] == 1) c++ ;        }        if(c == 1)  continue ;        f = 0 ;        printf("  SPF node %d leaves %d subnets\n",i,c);    }    if(f){        printf("  No SPF nodes\n");    }    printf("\n");}int main(){    int a, b , cas;    cas = 0 ;    while(true ){        scanf("%d",&a);        if(a == 0)  break ;        ++cas ;        init() ;        vis[a] = 1 ;        scanf("%d",&b);        vis[b] = 1 ;        g[a][b] = g[b][a] = 1 ;        while(1){            scanf("%d",&a);            if(a == 0)  break ;            scanf("%d",&b);            g[a][b] = g[b][a] = 1 ;            vis[a] = vis[b] = 1 ;        }        printf("Network #%d\n",cas);        solve() ;    }    return 0 ;}