理论知识看了好久的说、这里就不写了、
主要的是定义low[u]表示从u或u的子孙出发通过回边可以到达的最低深度优先数dfn[]。
low[u]=min{dfn[u], min{low[w]|w是u的子女}, min{dfn[v]|v与u邻接,且(u,v)是一条回边} }
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
int low[2010],dfn[2010],ss[1010],v[1010],p[2010],n1[2010],h[1010],n,e=0,tot=0;
inline void ae(int a,int b){ p[e]=b; n1[e]=h[a]; h[a]=e++;}
void dfs(int u){
for(int i=h[u];~i;i=n1[i]) if(!v[p[i]]){
v[p[i]]=1;
dfn[p[i]]=low[p[i]]=++tot;
dfs(p[i]);
low[u]=min(low[u],low[p[i]]);
if(low[p[i]]>=dfn[u]) ss[u]++;
}else low[u]=min(low[u],dfn[p[i]]);
}inline void init(){
memset(h,-1,sizeof(h));
memset(v,0,sizeof(v));
memset(ss,0,sizeof(ss));
e=0;tot=dfn[1]=low[1]=v[1]=1;
}int main(){
int u,v,Tc=0;
while(scanf("%d",&u),u){
init();
scanf("%d",&v);
ae(u,v); ae(v,u);
n=max(u,v);
while(scanf("%d",&u),u){
scanf("%d",&v);
n=max(n,max(u,v));
ae(u,v); ae(v,u);
}dfs(1);
if(Tc) printf("\n");
printf("Network #%d\n",++Tc);
int f=0;
if(ss[1]>=1) ss[1]--;
for(int i=1;i<=n;i++) if(ss[i]){
f=1;
printf(" SPF node %d leaves %d subnets\n",i,ss[i]+1);
}if(!f) printf(" No SPF nodes\n");
}return 0;
}