题目地址:POJ 1523
这题猛的一看。。貌似有点难的样子。不过仔细一想,那个每个割点所分成一次子图不就都能找到这个割点一次吗,那么只要记录下它作为割点的次数再+1不就行了。也算是求割点的裸题吧。这个题的输出很坑。。。需要注意一下。。
代码如下:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
int head[1100], cnt, index1, flag;
int low[1100], dfn[1100], ge[1100], vis[1100];
struct node
{
int u, v, next;
}edge[100000];
void add(int u, int v)
{
edge[cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void tarjan(int u, int fa)
{
low[u]=dfn[u]=++index1;
vis[u]=1;
int son=0, i;
for(i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
son++;
if(!vis[v])
{
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(u==1&&son>1||u!=1&&dfn[u]<=low[v])
{
ge[u]++;
flag=1;
}
}
else if(v!=fa)
low[u]=min(low[u],dfn[v]);
}
}
void init()
{
memset(head,-1,sizeof(head));
cnt=0;
memset(dfn,0,sizeof(dfn));
memset(vis,0,sizeof(vis));
memset(ge,0,sizeof(ge));
index1=0;
flag=0;
}
int main()
{
int u, v, i, j, num=0, n;
while(scanf("%d",&u)!=EOF&&u)
{
num++;
init();
scanf("%d",&v);
add(u,v);
add(v,u);
n=max(u,v);
while(scanf("%d",&u)!=EOF&&u)
{
scanf("%d",&v);
add(u,v);
add(v,u);
n=max(n,max(u,v));
}
tarjan(1,-1);
printf("Network #%d\n",num);
if(!flag)
{
printf(" No SPF nodes\n\n");
continue ;
}
for(i=1;i<=n;i++)
{
if(ge[i])
{
printf(" SPF node %d leaves %d subnets\n",i,ge[i]+1);
}
}
printf("\n");
}
return 0;
}