标签:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 7136 | Accepted: 3255 |
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
Source
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; const int MAXN = 10010; const int MAXM = 100010; struct Edge { int to,next; bool cut;//是否为桥的标记 } edge[MAXM]; int head[MAXN],tot; int Low[MAXN],DFN[MAXN],Stack[MAXN]; int Index,top; bool Instack[MAXN]; bool cut[MAXN]; int add_block[MAXN];//删除一个点后增加的连通块 int bridge; void addedge(int u,int v) { edge[tot].to = v; edge[tot].next = head[u]; edge[tot].cut = false; head[u] = tot++; } void Tarjan(int u,int pre) { int v; Low[u] = DFN[u] = ++Index; Stack[top++] = u; Instack[u] = true; int son = 0; for(int i = head[u]; i != -1; i = edge[i].next) { v = edge[i].to; if(v == pre)continue; if( !DFN[v] ) { son++; Tarjan(v,u); if(Low[u] > Low[v])Low[u] = Low[v]; if(Low[v] > DFN[u]) { bridge++; edge[i].cut = true; edge[i^1].cut = true; } if(u != pre && Low[v] >= DFN[u])//不是树根 { cut[u] = true; add_block[u]++; } } else if( Low[u] > DFN[v]) Low[u] = DFN[v]; } //树根,分支数大于1 if(u == pre && son > 1) cut[u] = true; if(u == pre) add_block[u] = son - 1; Instack[u] = false; top--; } void solve(int N) { memset(DFN,0,sizeof(DFN)); memset(Instack,0,sizeof(Instack)); memset(add_block,0,sizeof(add_block)); memset(cut,false,sizeof(cut)); Index = top = 0; int cnt = 0;//原来的连通块数 for(int i = 1; i <= N; i++) if( !DFN[i] ) { Tarjan(i,i);//找割点调用必须是Tarjan(i,i) cnt++; } int ans = 0; bool flag=true; for(int i = 1; i <= N; i++){ if(cut[i]==true){ flag=false; printf(" SPF node %d leaves %d subnets\n",i,add_block[i]+1); } } if(flag) printf(" No SPF nodes\n"); puts(""); } void init() { tot = 0; memset(head,-1,sizeof(head)); } int main() { int n,m; int u,v; int cas=0; while(scanf("%d",&u)!=EOF) { cas++; if(u==0) break; init(); scanf("%d",&v); addedge(u,v); addedge(v,u); n=max(u,v); while(scanf("%d",&u)!=EOF){ if(u==0) break; scanf("%d",&v); addedge(u,v); addedge(v,u); int temp=max(u,v); n=max(temp,n); } printf("Network #%d\n",cas); solve(n); } return 0; }
poj 1523 SPF 求割点以及删除该割点后联通块的数量
标签:
原文地址:http://www.cnblogs.com/13224ACMer/p/4781682.html