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