无向图割点的求法可以详见下一篇博文(包您满意)
题目大意:给定一个连通网络,网络的结点数<=1000,求出这个网络的所有割点编号,并求出若删去其中一个割点k后,对应的,原网络会被分割为多少个连通分量?
题目解析:前一部分是单纯求割点,而后一部分就要使成为割点的子节点数+1就行(还有父辈们一个),注意root不能加1哦(需要注意输出格式!)
代码如下:
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
int time,n,m,x,y,ans,top,j,ans1,ans2,root,tot;
int next[40005],to[40005],head[50001],dfn[50001],low[50001];
int in[50001],cut[50001],stack[40005],belong[40005],check[40005];
int zz[40005],ds[400005];
void add(int x,int y)
{
tot++;
next[tot]=head[x];
to[tot]=y;
head[x]=tot;
}
void dfs(int u,int fa)
{
int i;
if (fa!=-1)
{
ds[u]++;
}
in[u]=1;
stack[++top]=u;
low[u]=dfn[u]=++time;
int ok=0,son=0;
for(int i=head[u];i;i=next[i])
{
int v=to[i];
if (v==fa&&ok==0)
{
ok=1;
continue;
}
if (dfn[v]==0)
{
son++;
dfs(v,u);
if (low[v]>=dfn[u])
{
cut[u]=1;
ds[u]++;
}
if (low[v]>dfn[u]) ans2++;
low[u]=min(low[u],low[v]);
}
else if (in[v]==1)
{
low[u]=min(low[u],dfn[v]);
}
}
if (u==root)
{
if (son>1) cut[u]=1;
else cut[u]=0;
}
if(dfn[u]==low[u])
{
int hh;
do
{
hh=stack[top--];
belong[hh]=ans;
check[ans]++;
in[hh]=0;
}while(hh!=u);
ans++;
}
}
void hhhh()
{
memset(next,0,sizeof(next));
memset(to,0,sizeof(to));
memset(belong,0,sizeof(belong));
memset(check,0,sizeof(check));
memset(in,0,sizeof(in));
memset(head,0,sizeof(head));
memset(zz,0,sizeof(zz));
memset(ds,0,sizeof(ds));
memset(cut,0,sizeof(cut));
memset(belong,0,sizeof(belong));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(stack,0,sizeof(stack));
time=n=m=x=y=ans=top=j=ans1=ans2=root=tot=0;
}
int main()
{
int a;
scanf("%d",&a);
int kk=1;
while(a)
{
hhhh();
n=max(n,a);
scanf("%d",&m);
n=max(n,m);
add(a,m);
add(m,a);
scanf("%d",&x);
while(x)
{
n=max(n,x);
scanf("%d",&y);
n=max(n,y);
add(x,y);
add(y,x);
scanf("%d",&x);
}
for(int i=1;i<=n;i++)
{
if (dfn[i]==0)
{
root=i;
dfs(i,-1);
}
}
/*for(int i=1;i<=n;i++)
{
printf("%d ",belong[i]);
}
printf("\n");
/*for(int i=0;i<ans;i++)
{
printf("%d ",come[i]);
}*/
printf("Network #%d\n",kk++);
for(int i=1;i<=n;i++)
if (cut[i]) ans1++;
if(ans1==0)
{
printf(" No SPF nodes\n\n");
scanf("%d",&a);
continue;
}
int k=0;
for(int i=1;i<=n;i++)
if (cut[i])
{
zz[k++]=i;
}
sort(zz,zz+k);
for(int i=0;i<k;i++)
{
printf(" SPF node %d leaves %d subnets\n",zz[i],ds[zz[i]]);
}
printf("\n");
scanf("%d",&a);
}
return 0;
}
好了如果还有什么不懂的,可以给博主留言,或者直接加博主qq1067311025询问博主,不过博主可能是个蒟蒻,很菜。