POJ 1523 SPF 割点 dfs

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

求割点,还要判断割点把图分为几部分

WA了N次,if(!vs[v])chil[x]++是错误的,应为if(!vs[v]){...... if(dfn[x]<=low[v])child[x]++;

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#define nMAX 1005
using namespace std;
int map[nMAX][nMAX],dfn[nMAX],low[nMAX],cnt[nMAX];
int times,root,n,MIN,MAX;
int min(int a,int b)
{
    return a<b?a:b;
}
int max(int a,int b)
{
    return a>b?a:b;
}
void init()
{
    times=0;
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(cnt,0,sizeof(cnt));
    memset(map,0,sizeof(map));
}
void tarjan(int u,int fa)
{
    int son=0;
    dfn[u]=low[u]=++times;
    int v;
    for(v=MIN;v<=MAX;v++)
    {
        //邻接矩阵的就得考虑是否连通!!!
        if(!map[u][v])continue;
        if(!dfn[v])
        {

            tarjan(v,u);
            low[u]=min(low[u],low[v]);
           // if(dfn[u]<=low[v])
           //如果下面的cnt[u]++;改成son-1的话,上面的if必须加上
                son++;
            if(u==root&&son>=2)cnt[u]++;
            if(u!=root&&dfn[u]<=low[v])cnt[u]++;
        }
        else if(v!=fa)low[u]=min(low[u],dfn[v]);
    }
}
int main()
{
   int i,j,CASE=0;
   while(~scanf("%d",&i)&&i)
   {
       CASE++;
       MIN=nMAX,MAX=-1;
       init();
       MIN=min(MIN,i);
       MAX=max(MAX,i);
       scanf("%d",&j);
       MIN=min(MIN,j);
       MAX=max(MAX,j);
       map[i][j]=map[j][i]=1;
       while(~scanf("%d",&i)&&i)
       {
           MIN=min(MIN,i);
           MAX=max(MAX,i);
           scanf("%d",&j);
           MIN=min(MIN,j);
           MAX=max(MAX,j);
           map[i][j]=map[j][i]=1;
       }
       bool fg=0;
       root=MIN;
       tarjan(MIN,-1);
       printf("Network #%d\n",CASE);
       for(i=MIN;i<=MAX;i++)
       {
           if(!cnt[i])continue;
           fg=1;
           printf("  SPF node %d leaves %d subnets\n",i,cnt[i]+1);
       }
       if(!fg)printf("  No SPF nodes\n");
       printf("\n");
   }
   return 0;
}

  

posted @ 2012-02-29 23:59  快乐.  阅读(148)  评论(0编辑  收藏  举报