http://poj.org/problem?id=1523
求割点
并输出删去割点后能将图分成几部分
#include<stdio.h>
#include<string.h>
#define M 1005
struct node
{
int to,next;
}edge[M*M];
int tot;
int head[M];
bool cut[M];
int dfn[M],low[M];
int root_son;
int index;
int root;
bool vis[M];
void add(int a,int b)
{
edge[tot].to=b;
edge[tot].next=head[a];
head[a]=tot++;
}
void FindCut(int u)
{
int i,v;
dfn[u]=low[u]=index++;
for(i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].to;
if(!dfn[v])
{
FindCut(v);
if(u==root) root_son++;
else
{
if(low[v]<low[u])
low[u]=low[v];
if(low[v]>=dfn[u])
cut[u]=true;//判断是否为割点
}
}
else if(low[u]>=dfn[v])
low[u]=dfn[v];
}
}
void dfs(int u)
{
int i,b;
vis[u]=true;
for(i=head[u];i!=-1;i=edge[i].next)
{
b=edge[i].to;
if(!vis[b])
dfs(b);
}
}
int mx(int a,int b)
{
if(a>b) return a;
return b;
}
int main()
{
int u,v;
int i,j;
int max;
int cas=1,son;
bool flag;
while(scanf("%d",&u)&&u)
{
tot=0;
max=-1;
max=mx(max,u);
memset(head,-1,sizeof(head));
memset(cut,false,sizeof(cut));
memset(dfn,0,sizeof(dfn));
scanf("%d",&v);
max=mx(max,v);
add(u,v);
add(v,u);
while(scanf("%d",&u)&&u)
{
scanf("%d",&v);
max=mx(max,u);
max=mx(max,v);
add(u,v);
add(v,u);
}
root=1;
root_son=0;
index=1;
FindCut(root);
if(root_son>1) cut[root]=true;
printf("Network #%d\n",cas++);
flag=false;
for(i=1;i<=max;i++)
{
if(!cut[i]) continue;
flag=true;
memset(vis,false,sizeof(vis));
son=0;
vis[i]=true;
for(j=head[i];j!=-1;j=edge[j].next)//dfs,求割点i的子树有多少棵,即删去割点能将图分成及部分
{
if(!vis[edge[j].to])
{
dfs(edge[j].to);
son++;
}
}
printf(" SPF node %d leaves %d subnets\n",i,son);
}
if(!flag) printf(" No SPF nodes\n");
printf("\n");
}
return 0;
}