POJ3352 Road Construction Tarjan+边双连通
题目链接:http://poj.org/problem?id=3352
题目要求求出无向图中最少需要多少边能够使得该图边双连通。
在图G中,如果任意两个点之间有两条边不重复的路径,称为“边双连通”,去掉任何一条边都是其他边仍然是连通的,也就是说边双连通图中没有割边。
算法设计是:运用tarjan+缩点。对于每一个边双连通分量,我们都可以把它视作一个点,因为low值相同的点处在同一个边双连通分量中,可以简单地思考一下,(u,v)之间有两条可达的路径,dfs一定可以从一条路开始搜索并且从另一条路回去。而边双连通分量最初开始搜索的一个点的编号就是这个边双连通分量的low值,因为假设这个点的low值更加靠前的话,他与之前的结点一定是边双连通的关系,有一条边搜索到这个点,这个点在之后还有一条不重合的路径能到达先前那个结点,与边双连通分量的最大性产生矛盾,其实我们也可以把那个点收纳进这个边连通分量,把它作为该连通分量第一个进入dfs树的结点。故有边双连通分量中的点low值相同。
最终将这些点变成一个新的点图,这个点图中最大的边双连通分量就是一个点,所以我们只要看在这张图中需要加多少条边可以使得它边双连通就行。可以证明使得缩点图边双连通加上的边数是 (1+度数为1的点的数量)/2。由于这些缩点的low值都是不同的,所以我们可以用low值作为degree(点的度数)的索引。计算度数的时候时候扫描所有的点,只要跟一个low值不同的点有边,那么该low值(缩点)一定有一个外界的度(可看成入度),最后统计最终的只有一个度的连通分量数量即可。
用下面这张图同样可以证明为什么边双连通分量中的dfs中更新low值为什么是代码中所说的那样一个过程,因为low[3]是等于1的,而3的dfs顺序,就是dfn[3]=3,到了五号结点的时候,我们发现有回退边(5,3)如果此时我们用3的dfn值来更新5的low值的话就会发现5的low是3,回溯之后发现1,2,3结点low值是1,而4,5结点的low值是3,这样真的正确吗?很遗憾是错误的,为什么呢?我们可以发现,是因为在五号结点访问边(5,3)的时候错过了3号节点的回退边(3,1)在边双连通分量的计算中,回退边是需要包括在内的,这样dfs搜索到这个点之后这个点可以通过多条回退边跳回一个low=dfn结点,这个结点的low值就是他要更新成为的值。故边双连通分量中low的计算可以说是十分简洁但是要区分开和其他tarjan算法的low值计算策略,主要tarjan的这个low值太牛逼了!!!包含了太多的信息orz

代码如下:
#include<cstring>
#include<vector>
#include<stdio.h>
using namespace std;
const int maxn =;
int n,m,low[maxn],dfn;
vector<int>G[maxn];
void dfs(int u,int fa)//先用dfs处理处每个点的low值,以便相同的low值合并
{//处理low值时不需要处理dfn数组
low[u]=++dfn;
for(int i=;i<G[u].size();i++)
{
int v=G[u][i];
if(v==fa)continue;//保证dfs 树的前向性
if(!low[v])
dfs(v,u);
low[u]=min(low[u],low[v]);
}
}
int tarjan()
{
int degree[maxn];
memset(degree,,sizeof(degree));
for(int i=;i<=n;i++)
{
for(int j=;j<G[i].size();j++)
{
if(low[i]!=low[G[i][j]])
degree[low[i]]++;
}
}
int res=;
for(int i=;i<=n;i++)
{
if(degree[i]==)res++;
}
return res;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
int x,y;
memset(low,,sizeof(low));
for(int i=;i<=n;i++)G[i].clear();
while(m--)
{
scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
dfn=;//每次dfs之前设置dfs树的编号从1开始
dfs(,-);
int ans=tarjan();
printf("%d\n",(ans+)/);
}
return ;
}
POJ3352 Road Construction Tarjan+边双连通的更多相关文章
- POJ-3352 Road Construction,tarjan缩点求边双连通!
Road Construction 本来不想做这个题,下午总结的时候发现自己花了一周的时间学连通图却连什么是边双连通不清楚,于是百度了一下相关内容,原来就是一个点到另一个至少有两条不同的路. 题意:给 ...
- poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&&缩点】
Road Construction Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10141 Accepted: 503 ...
- POJ3352 Road Construction(边双连通分量)
...
- [POJ3352]Road Construction
[POJ3352]Road Construction 试题描述 It's almost summer time, and that means that it's almost summer cons ...
- POJ3352 Road Construction (双连通分量)
Road Construction Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Sub ...
- POJ3352 Road Construction 双连通分量+缩点
Road Construction Description It's almost summer time, and that means that it's almost summer constr ...
- POJ 3352 Road Construction(边—双连通分量)
http://poj.org/problem?id=3352 题意: 给出一个图,求最少要加多少条边,能把该图变成边—双连通. 思路:双连通分量是没有桥的,dfs一遍,计算出每个结点的low值,如果相 ...
- poj 3177 Redundant Paths(tarjan边双连通)
题目链接:http://poj.org/problem?id=3177 题意:求最少加几条边使得没对点都有至少两条路互通. 题解:边双连通顾名思义,可以先求一下连通块显然连通块里的点都是双连通的,然后 ...
- poj3352 Road Construction & poj3177 Redundant Paths (边双连通分量)题解
题意:有n个点,m条路,问你最少加几条边,让整个图变成边双连通分量. 思路:缩点后变成一颗树,最少加边 = (度为1的点 + 1)/ 2.3177有重边,如果出现重边,用并查集合并两个端点所在的缩点后 ...
随机推荐
- React.js/HTML5和iOS双向通信
最近,我使用WKWebView和React.js进行双向通信,自己写了React.js嵌入到Native中. Native操作Web,通过两种方式传值 第一种,通过JS传值给Native 通过这种方式 ...
- 神侃:反向激励能救活多少APP?
在很多宣扬互联网企业成功的宣传文案中,为了将其包装地更大高大上和有逼格,总是会将各种心理学术名词用上,以显示自己对市场.用户群体的观察入微.当然事实上所谓的心理学术名词,都是"马后炮&q ...
- ASP制作建议留言板
<html> <head> <meta http-equiv="Content-Type" content="text/html;cha ...
- ajax+lazyload时lazyload失效问题及解决
最近写公司的项目的时候遇到一个关于图片加载的问题,所做的页面是一个商城的商品列表页,其中需要显示商品图片,名称等信息,因为商品列表可能会很长,所以其中图片需要滑到可以显示的区域再进行加载. 首先我的图 ...
- CentOS下安装Anaconda和pycharm
前情提要:Linux越来越受大家喜爱,而在Linux中有一个社区很活跃的系统:那就是CentOS:而Anaconda又是几乎就一劳永逸的,你装了它之后基本上很多类库就不用再装了.然后就是pycharm ...
- 《深入理解 Java 虚拟机》读书笔记:虚拟机类加载机制
正文 虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型,这就是虚拟机的类加载机制. 一.类加载的时机 1.类的生命 ...
- java调用DLL,打印二维码标签
package com.ian.das.controller; import java.util.List; import org.xvolks.jnative.JNative; import org ...
- RestTemplate 负载均衡原理
RestTemplate 是通过拦截器改变请求的URI的方式来指定服务器的,此处将通过一个自定义LoadBalanced的方式来进行说明 1.导入jar包 <parent> <gro ...
- 必备技能七、Vuex
这段时间一直在用vue写项目,vuex在项目中也会依葫芦画瓢使用,但是总有一种朦朦胧胧的感觉.于是决定彻底搞懂它. 看了一下午的官方文档,以及资料,才发现vuex so easy! 作为一个圈子中的人 ...
- 数据结构 4 时间复杂度、B-树 B+树 具体应用与理解
前言 面试中,经常会问到有关于MYSQL 索引的相关概念,我们之前也都学过有关树的概念.以及二叉树.二叉查找树.红黑树等.这一节,来关注经常是数据库索引中使用的B-树 在说这些之前,我们需要了解时间复 ...