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;
}

浙公网安备 33010602011771号