标签:
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 7246 | Accepted: 3302 |
Description

Input
Output
Sample Input
1 2 5 4 3 1 3 2 3 4 3 5 0 1 2 2 3 3 4 4 5 5 1 0 1 2 2 3 3 4 4 6 6 3 2 5 5 1 0 0
Sample Output
Network #1 SPF node 3 leaves 2 subnets Network #2 No SPF nodes Network #3 SPF node 2 leaves 2 subnets SPF node 3 leaves 2 subnets
题意:求去掉割点之后 整个图分为多少个bcc 输出割点的编号以及去掉割点后bcc个数
割点:如果在无向图G中去掉一个顶点(自然同时去掉与该顶点相关联的所有边)后图的连通分支数增加,则称该顶点为G的割点
节点是割点的条件满足1或者2:
1、节点是根节点并且这个根节点有两个以及两个以上的子节点
2、节点不是根节点 满足dfn[u]<=low[v];
去掉割点后bcc增加的数目:
1:如果割点是根节点它的子节点数目为son去掉之后bcc增加son个
2:割点不是根节点它的子节点数目为son个去掉之后 bcc增加son+1个
#include<stdio.h>
#include<string.h>
#include<stack>
#include<algorithm>
#define MAX 2100
#define INF 0x7fffff
using namespace std;
int dfn[MAX],low[MAX];
int dfsclock,ebccnt;
int addbcc[MAX];//记录去掉割点后bcc个数
int head[MAX],ans;
int iscut[MAX];//记录是否是割点
struct node
{
int beg,end,next;
}edge[MAX];
void init()
{
ans=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v)
{
edge[ans].beg=u;
edge[ans].end=v;
edge[ans].next=head[u];
head[u]=ans++;
}
void tarjan(int u,int fa)
{
int i,v;
dfn[u]=low[u]=++dfsclock;
int son=0;//记录子节点数目
for(i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].end;
if(!dfn[v])
{
son++;
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(dfn[u]<=low[v])//是割点,先不考虑是不是根节点
{
addbcc[u]++;//这是割点的一个子节点,bcc数目加1
iscut[u]=1;
}
}
else
low[u]=min(dfn[v],low[u]);
}
if(fa<0&&son<2)//不是根节点
{
iscut[u]=0;
addbcc[u]=0;
}
if(fa<0&&son>1)//是根节点
{
iscut[u]=1;
addbcc[u]=son-1;//这里当是根节点时去掉割点bcc数目为子节点数目son
//但是因为上边我们for循环中求bcc时全部当做非根节点求这样
//其非根节点割点去掉之后bcc个数 为son+1,为了最后输出时统一加1
//这里我们让 addbcc[u]=son-1;
}
}
void find(int l,int r)
{
dfsclock=0;
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(addbcc,0,sizeof(addbcc));
memset(iscut,0,sizeof(iscut));
for(int i=l;i<=r;i++)
{
if(!dfn[i])
tarjan(i,-1);
}
}
int main()
{
int n,m,j,i,a,b;
int Max,Min;
int k=0;
while(1)
{
int t=0;
Max=-1;Min=INF;
init();
while(scanf("%d",&a)&&a!=0)
{
t++;
scanf("%d",&b);
Max=max(Max,max(a,b));
Min=min(Min,min(a,b));
add(a,b);
add(b,a);
}
if(a==0&&t==0)
break;
find(Min,Max);
int flag=0;
printf("Network #%d\n",++k);
for(i=Min;i<Max;i++)
{
if(iscut[i])
{
flag=1;
printf(" SPF node %d leaves %d subnets\n",i,addbcc[i]+1);
}
}
if(!flag)
printf(" No SPF nodes\n");
printf("\n");
}
return 0;
}
标签:
原文地址:http://www.cnblogs.com/tonghao/p/4890160.html