pku 1144 Network(tarjan算法求割点个数)

求无向图的割点个数。注意根结点是不是有多个儿子!!

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

 

#define MAXN 101
#define MAXM 10000

 

struct edge
{
    int adv,next;
};
edge p[MAXM];
int index;

int adjlist[MAXN];
int N,root=1,times,dfn[MAXN],low[MAXN];
bool cut[MAXN];

inline void insert(int i,int j)
{
    p[index].adv=j;
    p[index].next=adjlist[i];
    adjlist[i]=index++;
}

void print()
{
    int i,j;
    for(i=1;i<=N;i++)
    {
        printf("%d : ",i);
        for(j=adjlist[i]; j != -1; j=p[j].next)
        {
            printf("%d ",p[j].adv);
        }
        printf("\n");
    }
}

inline int Min(int a,int b)
{
    return a<b?a:b;
}

void dfs(int u,int ufa)
{
    int rootson=0;
    dfn[u]=low[u]=++times;
    for(int j=adjlist[u]; j != -1; j=p[j].next)
    {
        int v=p[j].adv;
        if( !dfn[v] )
        {
            if(u==root)
            {
                if(++rootson>1) cut[u]=true;//根有多个儿子,则是割点
            }
            dfs(v,u);
            low[u]=Min(low[u],low[v]);
            if( u != root && dfn[u] <= low[v]) cut[u]=true;//注意u!=root
        }
        else if(v!=ufa)
        {
            low[u]=Min(low[u],dfn[v]);
        }
    }
}

int main()
{
    int i,j;
    char ch;
    while(scanf("%d",&N),N)
    {
        index=0;
        memset(adjlist,-1,sizeof(adjlist));
        while(scanf("%d",&i),i)
        {
            while( (ch=getchar()) != '\n' )
            {
                scanf("%d",&j);
                insert(i,j);
                insert(j,i);
            }
        }
      //  print();
      memset(dfn,0,sizeof(dfn));
      memset(low,0,sizeof(low));
      memset(cut,false,sizeof(cut));
      times=0;
      dfs(root,-1);
      int cutnum=0;
      for(i=1;i<=N;i++)
        if(cut[i]) cutnum++;
      printf("%d\n",cutnum);
    }
    return 0;
}

 

posted @ 2010-08-18 17:14  菜到不得鸟  阅读(1066)  评论(0编辑  收藏  举报