标签:
题目链接:
http://poj.org/problem?id=1523
题目大意:
有一个网络,在这个网络里,电脑之间的通信只能是两台电脑间(点对点)双向通信。如下面左图
所示:如果3号电脑出故障了,那么1号和2号之间、4号和5号之间还可以通信,不过1、2和3、4
号电脑之间就不能通信了,那么3号电脑就是一个SPF节点,且3号电脑故障后,整个网络被分为
了2个子网络。那么问题来了:给你一些边。问删除某个SPF节点后,可以将图分为几个连通分量。
思路:
其实就是给你一个连通图,求出这个连通图的所有割点编号,并求出若删去其中一个割点后,原网
络被分成几个子网络。这里我们使用的思路和Tarjan算法类似。
(1)对原图进行深度优先搜索,计算树上每一个节点v的搜索深度标号dfn[v]。
(2)计算所有节点v的low[v]是在深度优先搜索树上按照后根遍历的顺序进行的。所以,当访问节点v
时它的儿子u的low[u]已经计算完毕,这时low[v]取下面三个值中的最小值。1.dfn[v]、2.dfn[w](凡
是含有回退边(v,w)的任何节点w)、3.low[u](对v的任何儿子u)
(3)然后判断一个点是不是割点,如果一个节点v是割点,满足下面两种情况。
1.v为树根,且v有多于一个子树;2.v不为树根,且满足存在边(v,u),使得dfn[v] <= low[u]。
注:我在程序中定义son[v]为节点v的深度,深度优先搜索时,每入栈一次,son[v]+1,每退栈一次,
son[v]-1。
AC代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; const int MAXN = 1010; const int MAXM = MAXN*MAXN; struct EdgeNode { int to; int next; }Edges[MAXM]; int Head[MAXN]; int dfn[MAXN],low[MAXN],Stack[MAXN],son[MAXN]; int m,id,scc,lay,N; void AddEdges(int u,int v) { Edges[id].to = v; Edges[id].next = Head[u]; Head[u] = id++; } void TarjanBFS(int pos,int from) { Stack[m++] = pos; dfn[pos] = low[pos] = ++lay; for(int i = Head[pos]; i != -1; i = Edges[i].next) { if(Edges[i].to == from) continue; if( !dfn[Edges[i].to]) { TarjanBFS(Edges[i].to,pos); low[pos] = min(low[pos],low[Edges[i].to]); if( dfn[pos] <= low[Edges[i].to] ) { while(Stack[m--] != Edges[i].to); son[pos]++; } } else low[pos] = min(low[pos],low[Edges[i].to]); } } int main() { int u,v,kase = 0; while(~scanf("%d",&u) && u) { N = -1; m = lay = scc = id = 0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(son,0,sizeof(son)); memset(Head,-1,sizeof(Head)); N = max(N,u); scanf("%d",&v); N = max(N,v); AddEdges(u,v); AddEdges(v,u); while(scanf("%d",&u) && u) { N = max(N,u); scanf("%d",&v); N = max(N,v); AddEdges(u,v); AddEdges(v,u); } printf("Network #%d\n",++kase); TarjanBFS(1,0); son[1]--; int flag = 0; for(int i = 1; i <= N; ++i) { if(son[i] > 0) { printf(" SPF node %d leaves %d subnets\n", i, son[i]+1); flag = 1; } } if(flag == 0) printf(" No SPF nodes\n"); printf("\n"); } return 0; }
标签:
原文地址:http://blog.csdn.net/lianai911/article/details/43865313