理论知识看了好久的说、这里就不写了、
主要的是定义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; }