poj 3352 Road Construction(边-双连通分量)
题意:给定一个连通的无向图G,至少要添加几条边,才能使其变为双连通图。
解题思路:
显然,当图G存在桥(割边)的时候,它必定不是双连通的。桥的两个端点必定分别属于图G的两个【边双连通分量】(注意不是点双连通分量),一旦删除了桥,这两个【边双连通分量】必定断开,图G就不连通了。但是如果在两个【边双连通分量】之间再添加一条边,桥就不再是桥了,这两个【边双连通分量】之间也就是双连通了。
首先要找出图G的所有【边双连通分量】。
Tarjan算法用来寻找图G的所有【边双连通分量】是最简单有效的方法,因为Tarjan算法在DFS过程中会对图G所有的结点都生成一个Low值,而由于题目已表明任意两个结点之间不会出现重边,因此Low值相同的两个结点必定在同一个【边双连通分量】中! (如果是有重边的话,那么不同的low值是可能是属于同一个边双连通分量的,这个时候就要通过其他方法去求解边双连通分量。不过这不是本题要讨论的)
把每一个【边双连通分量】都看做一个点(即【缩点】)
也有人称【缩点】为【块】,都是一样的。其实缩点不是真的缩点,只要利用Low值对图G的点分类处理,就已经缩点了。
至少增加的边数 =( 这棵树总度数为1的结点数 + 1 )/ 2
这个证明可以数学归纳法简单证明。
参考博客:http://blog.csdn.net/lyy289065406/article/details/6762370
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;const int maxn = 1005;
struct Edge
{int from,to,next;bool cut;
}edge[maxn<<1];
int n,m,cnt,head[maxn];
int top,Index,block,Stack[maxn],ind[maxn];
int bel[maxn],low[maxn],dfsn[maxn];
bool Instack[maxn];void init()
{cnt = top = Index = block = 0;memset(head,-1,sizeof(head));memset(dfsn,0,sizeof(dfsn));memset(ind,0,sizeof(ind));memset(Instack,false,sizeof(Instack));
}void addedge(int u,int v)
{edge[cnt].to = v;edge[cnt].from = u;edge[cnt].cut = false;edge[cnt].next = head[u];head[u] = cnt++;
}void Tarjan(int u,int fa)
{low[u] = dfsn[u] = ++Index;Stack[top++] = u;Instack[u] = true;for(int i = head[u]; i != -1; i = edge[i].next){int v = edge[i].to;if(v == fa) continue;if(dfsn[v] == 0){Tarjan(v,u);if(low[v] < low[u])low[u] = low[v];if(low[v] > dfsn[u]){edge[i].cut = true;edge[i^1].cut = true;}}else if(Instack[v] && low[u] > dfsn[v])low[u] = dfsn[v];}if(low[u] == dfsn[u]){int v;block++;do{v = Stack[--top]; bel[v] = block;Instack[v] = false; }while(v != u);}
}int main()
{int u,v;while(scanf("%d%d",&n,&m)!=EOF){init();for(int i = 1; i <= m; i++){scanf("%d%d",&u,&v);addedge(u,v);addedge(v,u);}for(int i = 1; i <= n; i++)if(!dfsn[i])Tarjan(i,-1);for(int i = 0; i < 2*m; i += 2){u = edge[i].from, v = edge[i].to;if(bel[u] != bel[v])ind[bel[u]]++,ind[bel[v]]++;}int leaf = 0;for(int i = 1; i <= block; i++)if(ind[i] == 1)leaf++;printf("%d\n",(leaf+1)/2);}return 0;
}
poj 3352 Road Construction(边-双连通分量)相关推荐
- POJ 3177 Redundant Paths POJ 3352 Road Construction(双连接)
POJ 3177 Redundant Paths POJ 3352 Road Construction 题目链接 题意:两题一样的.一份代码能交.给定一个连通无向图,问加几条边能使得图变成一个双连通图 ...
- Tarjan算法求解桥和边双连通分量(附POJ 3352 Road Construction解题报告)
http://blog.csdn.net/geniusluzh/article/details/6619575 在说Tarjan算法解决桥和边双连通分量问题之前我们先来回顾一下Tarjan算法是如何求 ...
- POJ 3352 Road Construction ; POJ 3177 Redundant Paths (双联通)
这两题好像是一样的,就是3177要去掉重边. 但是为什么要去重边呢??????我认为如果有重边的话,应该也要考虑在内才是. 这两题我用了求割边,在去掉割边,用DFS缩点. 有大神说用Tarjan,不过 ...
- Redundant Paths POJ - 3177(tarjan+边双连通分量)
题意: 有n个牧场,要求从一个牧场到另一个牧场,要求至少要有2条独立的路可以走.现已有m条路,求至少要新建多少条路,使得任何两个牧场之间至少有两条独立的路.两条独立的路是指:没有公共边的路,但可以经过 ...
- POJ 1523 SPF (割点 点双连通分量)
题意:求出割点以及除去割点后的连通分量的数量(附带求出了点双连通分量(块)) [求割点]对图深度优先搜索,定义DFS(u)为u在搜索树(以下简称为树)中被遍历到的次序号.定义Low(u)为u或u的子树 ...
- 【POJ - 3352】Road Construction(Tarjan,边双连通分量)
题干: It's almost summer time, and that means that it's almost summer construction time! This year, th ...
- poj 3352 双连通分量
至少加几条边成为双连通分量 #include <iostream> #include <cstdio> #include <cstring> using names ...
- POJ 3352 无向图边双连通分量,缩点,无重边
为什么写这道题还是因为昨天多校的第二题,是道图论,HDU 4612.当时拿到题目的时候就知道是道模版题,但是苦于图论太弱.模版都太水,居然找不到.虽然比赛的时候最后水过了,但是那个模版看的还是一知半解 ...
- 【POJ - 3177】Redundant Paths(边双连通分量,去重边)
题干: In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1.. ...
最新文章
- cocos2d-x 3.x 场景切换特效大集合
- 【转】 [C/OC的那点事儿]NSMutableArray排序的三种实现(依赖学生成绩管理系统).
- 谈谈一些有趣的CSS题目(十五)-- 谈谈 CSS 关键字 initial、inherit 和 unset
- wpf listview 使用
- LYNC文件传输功能开关
- arraylist能否接收强转类型_ArrayList 源码解析
- centos sudo不能运行_如何在Linux中配置sudo访问权限
- Launcher分析修改记录(1)----序
- 枚举一个集合的所有子集
- Fourier分析基础(二)——由级数导出连续Fourier变换
- springmvc请求参数获取的几种方法
- 免费网络管理软件大全
- 基于台达PLC的步进电机控制
- 基于JSP+Servlet的旅游景点服务平台(旅游网站)
- 2019年6款最佳的wordpress主机推荐(优缺点分析)
- 这里给详细解答一下自己办理商标注册的申请流程
- mysql的genelog_小白实战课堂!转录因子的候选靶基因查询~~
- 杭州电子科技大学程序设计竞赛(2016’12)
- [VBA]EXCEL表格,运行VBA报错:运行时错误‘9’ 下标越界
- python爬虫之多线程、多进程爬虫