SPF
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int edge[1010][1010];//邻接矩阵
int vis[1010];//表示顶点访问状态
int node;//顶点数目
int tmpdfn;//在dfs过程中记录当前的深度优先搜索序数
int dfn[1010];//每个顶点的dfn值
int low[1010];//每个顶点的low值,根据该值来判断是否是关节点
int son;//根节点的子女节点的个数,如果>2,则根节点是关节点
int subnets[1010];//记录每个节点的联通分量个数(去掉该节点后)
void dfs(int u)//深度优先搜索,记录每个节点的low值(根据low值判断是否求关节点
{
for(int v=1;v<=node;v++)
{
//v和u邻接,在生成树中就是2中情况
//1.v是u的祖先节点,这样(v,u)就是一条边
//2.v是u的儿子节点
if(edge[u][v])
{
if(!vis[v])//v还未访问,v是u的儿子节点
{
vis[v]=1;
tmpdfn++;
dfn[v]=low[v]=tmpdfn;
dfs(v);//dfs(v)执行完毕后,low[v]值已求出
low[u]=min(low[u],low[v]);//回退的时候,计算顶点u的low值
if(low[v]>=dfn[u])
{
if(u!=1)subnets[u]++;//去掉该节点后的连通分量个数
//根节点的子女节点的个数(如果>2,则根节点是关节点
if(u==1)son++;
}
}
//此前v已经访问过了,v是u的祖先节点((v,u)就是一条回边)
else
low[u]=min(low[u],dfn[v]);
}
}
}
void init()//初始化函数
{
low[1]=dfn[1]=1;
tmpdfn=1,son=0;
memset(vis,0,sizeof vis);
vis[1]=1;
memset(subnets,0,sizeof subnets);
}
int main()
{
int i;
int u,v;//从输入文件中读入发顶点对
int find;//是否找到SPF节点的标志
int number=1;//测试数据数目
while(1)
{
scanf("%d",&u);
if(u==0)break;
memset(edge,0,sizeof edge);
node=0;
scanf("%d",&v);
if(u>node)node=u;
if(v>node)node=v;
edge[u][v]=edge[v][u]=1;
while(1)
{
scanf("%d",&u);
if(u==0)break;
scanf("%d",&v);
if(u>node)node=u;
if(v>node)node=v;
edge[u][v]=edge[v][u]=1;
}
if(number>1)
printf("\n");
printf("Network #%d\n",number);
number++;
init();
dfs(1);
if(son>1)
subnets[1]=son-1;
find=0;
for(i=1;i<=node;i++)
{
if(subnets[i])
{
find=1;
printf(" SPF node %d leaves %d subnets\n",i,subnets[i]+1);
}
}
if(!find)printf(" No SPF nodes\n");
}
/*
1 2
5 4
3 1
3 2
3 4
3 5
0
*/
return 0;
}