pku1523 SPF

(1)求割点。割点距离各连通分支有一边距离(父子边),故使用<=
(2)求割边。割边两端点分别在两个连通分支之中,故使用<
(3)求去除割点u后形成的连通分支数。若dfn[u]<lowlink[v],则uv为一割边,对应一个连通分支;若dfn[u]==lowlink[v],则表示割点u和v所在的连通分支之间只有父子边uv相连,除掉后亦可得到一连通分支。

 

 

#include <iostream>
using namespace std;

#define MAXN 1001
#define Min(a,b)(a<b?a:b)

int p[MAXN],ecnt,dfn[MAXN],lowlink[MAXN],sign,subSCC[MAXN],root,odeg[MAXN],T;
bool exist[MAXN],cut[MAXN];

struct Edge{
    
int v,next;
}edg[
10*MAXN];

void init(){
    sign
=0;
    ecnt
=0;
    memset(cut,
false,sizeof(cut));
    memset(odeg,
0,sizeof(odeg));
    
//memset(subSCC,0,sizeof(subSCC));
    memset(exist,false,sizeof(exist));
    memset(p,
-1,sizeof(p));
    memset(dfn,
-1,sizeof(dfn));
    
for(int i=1;i<MAXN;i++)
        subSCC[i]
=1;////根所在的连通分支在dfs中没有被统计
}

void dfs(int pre,int u){
    
int i,v;
    dfn[u]
=lowlink[u]=++sign;
    
for(i=p[u];i!=-1;i=edg[i].next){
        v
=edg[i].v;
        odeg[u]
++;
        
if(dfn[v]!=-1){
            
if(v!=pre)//(2)
                lowlink[u]=Min(lowlink[u],dfn[v]);
        }
        
else{
            dfs(u,v);
            lowlink[u]
=Min(lowlink[u],lowlink[v]);
            
//(1)
            if(u!=root && dfn[u]<=lowlink[v])
                cut[u]
=true;//cut[u]为true表示u为割点。这里改用计数器的话会重复计数
            else if(u==root && odeg[root]>1)//DFS树的根r是割点的充要条件是:至少有2条以r为尾(从r出发)的父子边
                cut[u]=true;
            
//(2)
            
//if(bfn[u]<lowlink[v])
            
//    Brige[u,v] is true;//边uv是桥
            
//(3)
            if(u!=root && dfn[u]<=lowlink[v])
                subSCC[u]
++;
            
else if(u==root)
                subSCC[u]
=odeg[u];
            
        }
    }
}
                



void solve(){
    
int i;
    
bool ok=false;
    root
=1;
    
while(!exist[root])
        root
++;
    
for(i=1;i<MAXN;i++)
        
if(exist[i] && dfn[i]==-1)
            dfs(
-1,i);

    printf(
"Network #%d\n",T++);
    
for(i=1;i<MAXN;i++){
        
if(cut[i]){
            ok
=true;
            printf(
"  SPF node %d leaves %d subnets\n",i,subSCC[i]);
        }
    }
    
if(!ok){
        printf(
"  No SPF nodes\n");
    }
    printf(
"\n");
}

int main(){
    T
=1;
    
int u,v;
    
while(scanf("%d",&u) && u){
        init();
        scanf(
"%d",&v);
        edg[ecnt].v
=v;
        edg[ecnt].next
=p[u];
        p[u]
=ecnt++;
        edg[ecnt].v
=u;
        edg[ecnt].next
=p[v];
        p[v]
=ecnt++;
        exist[u]
=exist[v]=true;
        
while(scanf("%d",&u) && u){
            scanf(
"%d",&v);
            edg[ecnt].v
=v;
            edg[ecnt].next
=p[u];
            p[u]
=ecnt++;
            edg[ecnt].v
=u;
            edg[ecnt].next
=p[v];
            p[v]
=ecnt++;
            exist[u]
=exist[v]=true;
        }
        solve();
    }
    
return 0;
}


 

posted @ 2009-01-18 21:47  Beetlebum  阅读(479)  评论(3编辑  收藏  举报