标签:
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