POJ1523 SPF【点双连通分量】【Tarjan】
来源:互联网 发布:淘宝开店邮费是多少 编辑:程序博客网 时间:2024/05/16 15:24
题目链接:
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;}
0 0
- POJ1523 SPF【点双连通分量】【Tarjan】
- 【POJ1523】SPF tarjan求点-双连通分量 裸题模板题
- POJ 1523SPF 点双连通分量
- 点/边 双连通分量---Tarjan算法
- tarjan求点的双连通分量
- BZOJ1123 BLO [Tarjan][点双连通分量]
- 双连通分量-tarjan
- 双连通分量-tarjan
- POJ 1523 SPF (割顶 点双连通分量)
- 点双连通分量
- 点双连通分量
- 点双连通分量
- 点双连通分量
- 【tarjan求解双连通分量】
- [双连通分量] tarjan算法
- tarjan算法-双连通分量
- 关于Tarjan算法求点双连通分量
- 点双连通分量的求解 Tarjan算法的拓展
- 5分钟打造bootstrap网页
- 黑马程序员---从头开始,回忆JAVA基础之IO流(一)
- 数据结构和算法
- 模拟解Spinning Wheels
- Pat 1069(同basic level里的1019)
- POJ1523 SPF【点双连通分量】【Tarjan】
- 用润乾集算报表实现实时报表(T+0)的方案
- 遭遇DBD::mysql::dr::imp_data_size unexpectedly
- 使用微信SDK时,出现了 "operator new[](unsigned long)", referenced from:等问题的解决方法
- Sizeof与Strlen的区别与联系(转)
- Service与Android系统实现
- Linux安装源代码包流程
- 网络ISO/OSI参考模型
- valgrind massif检测内存使用比例