题解转自http://blog.csdn.net/lyy289065406/article/details/6762370   文中部分思路或定义模糊,重写的红色部分为修改过的。

大致题意:

  某个企业想把一个热带天堂岛变成旅游胜地,岛上有N个旅游景点,保证任意2个旅游景点之间有路径连通的(可间接连通)。而为了给游客提供更方便的服务,该企业要求道路部门在某些道路增加一些设施。

  道路部门每次只会选择一条道路施工,在该条道路施工完毕前,其他道路依然可以通行。然而有道路部门正在施工的道路,在施工完毕前是禁止游客通行的。这就导致了在施工期间游客可能无法到达一些景点。

  为了在施工期间所有旅游景点依然能够正常对游客开放,该企业决定搭建一些临时桥梁,使得不管道路部门选在哪条路进行施工,游客都能够到达所有旅游景点。给出当下允许通行的R条道路,问该企业至少再搭建几条临时桥梁,才能使得游客无视道路部门的存在到达所有旅游景点?

  题目所给的图是连通的,且所给的边没有重复的,所以不考虑重边。

   注意:不要把Sample Input 1读入,更不要把它输出!!!!!

首先建立模型:

给定一个连通的无向图G,至少要添加几条边,才能使其变为边-双连通图(因为在修道路是一条边!)。

模型很简单,正在施工的道路我们可以认为那条边被删除了。那么一个图G能够在删除任意一条边后,仍然是连通的,当且仅当图G至少为边双连通的。

PS:不要问我为什么不是3-连通、4-连通...人家题目问“至少添加几条边”好不...

显然,当图G存在桥(割边)的时候,它必定不是边双连通的。桥的两个端点必定分别属于图G的两个【边双连通分量】(注意不是点双连通分量),一旦删除了桥,这两个【边双连通分量】必定断开,图G就不连通了。但是如果在两个【边双连通分量】之间再添加一条边,桥就不再是桥了,这两个【边双连通分量】之间也就是边双连通了。

那么如果图G有多个【边双连通分量】呢?至少应该添加多少条边,才能使得任意两个【边双连通分量】之间都是边双连通的(也就是图G是边双连通的)?

这个问题就是本题的问题。要解决这个问题:

1、  首先要找出图G的所有【边双连通分量】。

Tarjan算法用来寻找图G的所有【边双连通分量】是最简单有效的方法,因为Tarjan算法在DFS过程中会对图G所有的结点都生成一个Low值,而由于题目已表明任意两个结点之间不会出现重边,因此Low值相同的两个结点必定在同一个【边双连通分量】中(但是!!low值不同的点并不代表就不在同一个边双连通分量中,因为由于先后访问的顺序的原因,low值可能会不同,这跟并查集的道理是一样的,如果不进行压缩路径,几乎很多人的直接上级都不会是该团队的boss,这点可以模仿并查集的方式将其归到只有两层,查起来就很快了,否则可能超时!!当然你不考虑这点也能AC,水果了那些简单数据,但是下面这2组数据你可能过不了)!

11 14
1 2
1 3
1 4
2 5
6 11
2 6
5 6
5 11
3 7
3 8
7 8
4 9
4 10
9 10

11 14
1 2
1 3
1 4
5 11
2 5
2 6
5 6
6 11
3 7
3 8
7 8
4 9
4 10
9 10

以上两个测试数据的ans都是2。

2、  把每一个【边双连通分量】都看做一个点(即【缩点】)

也有人称【缩点】为【块】,都是一样的。其实缩点不是真的缩点,只要利用Low值对图G的点分类处理,就已经缩点了。

以样例1为例,样例1得到的图G为上左图,

其中Low[4]=Low[9]=Low[10]

Low[3]=Low[7]=Low[8]

Low[2]=Low[5]=Low[6]

Low[1]独自为政....

把Low值相同的点划分为一类,每一类就是一个【边双连通分量】,也就是【缩点】了,不难发现,连接【缩点】之间的边,都是图G的桥,那么我们就得到了上右图以缩点为结点,以桥为树边所构造成的树。

  以上这样以low值判断边连通分量是没有错的!只是要确保low值能区分出该块,当然,你可以用栈,就像求点双连通分量那样(并不是完全一样,那是以割点来区分的,这是以桥来区分的)。

3、  问题再次被转化为“至少在缩点树上增加多少条树边,使得这棵树变为一个边双连通图”。

首先知道一条等式:

若要使得任意一棵树,在增加若干条边后,变成一个双连通图,那么

至少增加的边数 =( 这棵树总度数为1的结点数 + 1 )/ 2

(证明就不证明了,自己画几棵树比划一下就知道了)

那么我们只需求缩点树中总度数为1的结点数(不一定是叶子数,如果树根仅有1个孩子,同样要将其统计进来)有多少就可以了。换而言之,我们只需求出所有缩点的度数,然后判断度数为1的缩点有几个,问题就解决了。

4、  求出所有缩点的度数的方法

两两枚举图G的直接连通的点(如果求出了桥,那么枚举桥也行的,相同于直接枚举树的边),只要这两个点不在同一个【缩点】中,那么它们各自所在的【缩点】的度数都+1。注意由于图G时无向图,这样做会使得所有【缩点】的度数都是真实度数的2倍,必须除2后再判断是否度为1。

特别注意:求【点双连通分量】与【边双连通分量】是不同的模板,勿混淆。

 #include <iostream>
#include <cmath>
#include <cstdio>
#include <vector>
#include <cstring>
#include <set>
//#include <bits/stdc++.h>
using namespace std;
const int N=+;
vector<int> vect[N];
int low[N], dfn[N], cnter;
int du[N];
int pre[N];//这个与dfn是相反的索引
vector<pair<int,int> > cutt;
int find(int x) //寻找x的low值
{
if(low[x]==dfn[x]) return low[x];
return low[x]=find( pre[low[x] ] );
} void DFS(int x, int far)
{
low[x]= dfn[x]= ++cnter;
pre[cnter]=x; //标记第cnter个访问的是谁
for(int i=; i<vect[x].size(); i++)
{
int t=vect[x][i];
if(!dfn[t])
{
DFS(t,x);
low[x]=min(low[x],low[t]);
if(low[t]>dfn[x]) cutt.push_back(make_pair(x,t));//桥(即树边)
}
else if(t!=far) low[x]=min(low[x],dfn[t]);
}
} int cal_bcc(int f)
{
cutt.clear();
memset(du,,sizeof(du));
memset(low,,sizeof(low));
memset(dfn,,sizeof(dfn));
memset(pre,,sizeof(pre));
cnter=;
DFS(,);
for(int i=; i<cutt.size(); i++)
{
int a=cutt[i].first;
int b=cutt[i].second;
du[find(a)]++;
du[find(b)]++;
} int ans=;
for(int i=; i<=f; i++) if(du[i]==) ans++;
return ((ans+)/);
} int main()
{
//freopen("input.txt", "r", stdin);
int f, r, a, b, j=;
char s[N];
while(cin>>f>>r)
{
for(int i=; i<=f; i++) vect[i].clear();
while(r--)
{
scanf("%d%d", &a, &b);
vect[a].push_back(b);
vect[b].push_back(a);
}
printf("%d\n",cal_bcc(f));
}
return ;
}

AC代码

POJ 3352 Road Construction(边双连通分量,桥,tarjan)的更多相关文章

  1. POJ 3177 Redundant Paths & POJ 3352 Road Construction(双连通分量)

    Description In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numb ...

  2. POJ 3352 Road Construction (边双连通分量)

    题目链接 题意 :有一个景点要修路,但是有些景点只有一条路可达,若是修路的话则有些景点就到不了,所以要临时搭一些路,以保证无论哪条路在修都能让游客到达任何一个景点 思路 :把景点看成点,路看成边,看要 ...

  3. poj 3352 Road Construction(边双连通分量+缩点)

    题目链接:http://poj.org/problem?id=3352 这题和poj 3177 一样,参考http://www.cnblogs.com/frog112111/p/3367039.htm ...

  4. POJ 3177 Redundant Paths POJ 3352 Road Construction(双连接)

    POJ 3177 Redundant Paths POJ 3352 Road Construction 题目链接 题意:两题一样的.一份代码能交.给定一个连通无向图,问加几条边能使得图变成一个双连通图 ...

  5. Tarjan算法求解桥和边双连通分量(附POJ 3352 Road Construction解题报告)

     http://blog.csdn.net/geniusluzh/article/details/6619575 在说Tarjan算法解决桥和边双连通分量问题之前我们先来回顾一下Tarjan算法是如何 ...

  6. POJ 3352 Road Construction(边—双连通分量)

    http://poj.org/problem?id=3352 题意: 给出一个图,求最少要加多少条边,能把该图变成边—双连通. 思路:双连通分量是没有桥的,dfs一遍,计算出每个结点的low值,如果相 ...

  7. poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&&缩点】

    Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10141   Accepted: 503 ...

  8. POJ 3352 Road Construction 双联通分量 难度:1

    http://poj.org/problem?id=3352 有重边的话重边就不被包含在双连通里了 割点不一定连着割边,因为这个图不一定是点连通,所以可能出现反而多增加了双连通分量数的可能 必须要用割 ...

  9. poj 3352 : Road Construction 【ebcc】

    题目链接 题意:给出一个连通图,求最少加入多少条边可使图变成一个 边-双连通分量 模板题,熟悉一下边连通分量的定义.最后ans=(leaf+1)/2.leaf为原图中size为1的边-双连通分量 #i ...

随机推荐

  1. bzoj 4010: [HNOI2015]菜肴制作 拓扑排序

    题目链接: 题目 4010: [HNOI2015]菜肴制作 Time Limit: 5 Sec Memory Limit: 512 MB 问题描述 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴 ...

  2. 【UVA】【11427】玩纸牌

    数学期望 也是刘汝佳老师白书上的例题……感觉思路很神奇啊 //UVA 11427 #include<cmath> #include<cstdio> #include<cs ...

  3. 【锋利的JQuery-学习笔记】输入框提示语-隐藏/显示

    html <div class="search"> <input type="text" id="inputSearch" ...

  4. SVN库实时同步设置

    为了安全起见,SVN服务器除了做定时全量备份和增量备份以外,如条件允许,可做实时备份. 这需要2台机器,一台是master server,另一台做mirror server.master做主服务,mi ...

  5. linux故障救援

    今天手贱,误操作将/usr/lib整个文件夹都删了.但是系统内还有很多重要的文件和数据,不敢贸然重装系统. 弄了个u盘启动. 一开始整个系统只有一个分区,原系统装在这个分区里,我用u盘启动后,用分区管 ...

  6. 【redis】01Redis的介绍与安装部署

    单元目标: 1.NoSQL介绍 2.Redis的介绍 3.Redis适用场合 4.Redis的安装与部署 5.Redis的数据类型 6.Redis的常用命令 7.Redis的高级应用       通过 ...

  7. POJ 1906

    #include <iostream> #include <string> #define MAXN 150 using namespace std; int _m[MAXN] ...

  8. grunt安装失败处理

    1.官网 Grunt官网 http://gruntjs.com 2.前言 前段时间一不小心升级了win10(万恶的360),各种不适应各种问题各种软件bug,最终决定回退到win7,然后悲催的发现系统 ...

  9. Python中Lambda, filter, reduce and map 的区别

    Lambda, filter, reduce and map Lambda Operator Some like it, others hate it and many are afraid of t ...

  10. Use windows batch script to create menu

    Background Recently, I find that we need  to  type some very long gradle commands to run build, chec ...