题意:问去掉每一个割点后的联通分支数;
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
const int N = 1009;
struct LT{
int nex,to;
}L[N*N];
int F[N],cnt;
int has[N];
int re[N],rcnt;
void add(int f,int t)
{
L[cnt].nex = F[f];
L[cnt].to = t;
F[f] = cnt++;
}
bool init()
{
int c=1;
cnt=1;rcnt=1;
memset(F,0,sizeof(F));
memset(has,0,sizeof(has));
int f,t;
while(1)
{
scanf("%d",&f);
if(f==0)
{
if(c==1) return false;
return true;
}
c=0;
scanf("%d",&t);
if(!has[f]) re[rcnt]=f,has[f] = rcnt,rcnt++;
if(!has[t]) re[rcnt]=t,has[t] = rcnt,rcnt++;
add(has[f],has[t]);
add(has[t],has[f]);
}
}
int dfn[N],low[N],ind,head,son,ans[N];
void tarjan(int k,int fa)
{
//cout<<k<<" "<<fa<<endl;
dfn[k] = low[k] = ind++;
for(int i=F[k];i;i=L[i].nex)
{
int to = L[i].to;
if(to == fa) continue;
if(!dfn[to])
{
tarjan(to,k);
if(dfn[k]<=low[to])
ans[k]++;
else
low[k] = min(low[k],low[to]);
}
else
low[k] = min(low[k],dfn[to]);
}
}
struct node{
int v,ans;
bool operator<(const node t) const
{
return v<t.v;
}
} vv[N];
void solve(int T)
{
memset(dfn,0,sizeof(dfn));
memset(ans,0,sizeof(ans));
ans[1]=-1;ind = 1;
tarjan(1,-1);
int a=0;
for(int i=1;i<rcnt;i++)
{
if(ans[i]>0)
{
vv[a].v=re[i],vv[a].ans=ans[i]+1;
a++;
}
}
printf("Network #%d\n",T);
if(a==0)
{
printf(" No SPF nodes\n\n");
return ;
}
sort(vv,vv+a);
for(int i=0;i<a;i++)
{
printf(" SPF node %d leaves %d subnets\n",vv[i].v,vv[i].ans);
}
printf("\n");
}
int main()
{
freopen("in.txt","r",stdin);
int T=1;
while(init()) solve(T),T++;
return 0;
}