POJ 3177 Redundant Paths (边双连通+缩点)
<题目链接>
<转载于 >>> >
题目大意:
有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走。现已有m条路,求至少要新建多少条路,使得任何两个牧场之间至少有两条独立的路。两条独立的路是指:没有公共边的路,但可以经过同一个中间顶点。
解题分析:
在同一个边双连通分量中,任意两点都有至少两条独立路可达,所以同一个边双连通分量里的所有点可以看做同一个点。
缩点后,新图是一棵树,树的边就是原无向图的桥。
现在问题转化为:在树中至少添加多少条边能使图变为双连通图。
结论:添加边数=(树中度为1的节点数+1)/2
具体方法为,首先把两个最近公共祖先最远的两个叶节点之间连接一条边,这样可以把这两个点到祖先的路径上所有点收缩到一起,因为一个形成的环一定是双连通的。然后再找两个最近公共祖先最远的两个叶节点,这样一对一对找完,恰好是(leaf+1)/2次,把所有点收缩到了一起。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int N = 5e3+ , M = 1e4+;
#define clr(a,b) memset(a,b,sizeof(a))
struct Edge{
int to,next;
}edge[M<<]; int head[N],low[N],dfn[N],belong[N],deg[N],stk[N],instk[N];
int n,m,tot,cnt,top,scc;
void addEdge(int u,int v){
edge[tot].to=v,edge[tot].next=head[u];
head[u]=tot++;
}
void init(){
tot=cnt=top=scc=;
clr(head,-);clr(low,);clr(dfn,);clr(instk,);clr(deg,);
}
void Tarjan(int u,int fa){
low[u]=dfn[u]=++cnt;
stk[++top]=u;instk[u]=;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(i==(fa^))continue; //不能用搜索树上的边来更新low值,这种写法能够用来处理重边的情况
if(!dfn[v]){
Tarjan(v,i);
low[u]=min(low[u],low[v]);
}
else if(instk[v]) //此时栈里的所有元素均属于同一边双连通分量,找连通分量的根的时候一定要规定这点,否则可能会与其他连通分量的dfn比较
low[u]=min(low[u],dfn[v]); //low值全部等于该双连通分量中最先遍历的点dfn值
}
if(dfn[u]==low[u]){
++scc;
while(true){
int v=stk[top--];
instk[v]=;
belong[v]=scc; //将该联通块中的所有点全部缩点染色
if(v==u)break;
}
}
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
init();
for(int i=;i<=m;i++){
int u,v;scanf("%d%d",&u,&v);
addEdge(u,v),addEdge(v,u);
}
Tarjan(,-);
for(int i=;i<=n;i++){
for(int j=head[i];j!=-;j=edge[j].next){
int v=edge[j].to;
if(belong[i]!=belong[v])
deg[belong[i]]++; //求出缩点后每个点的度
}
}
int sum=;
for(int i=;i<=scc;i++)if(deg[i]==)sum++; //寻找度为1的叶子节点
int ans=(sum+)/;
printf("%d\n",ans);
}
}
2018-11-07
POJ 3177 Redundant Paths (边双连通+缩点)的更多相关文章
- poj 3177 Redundant Paths(边双连通分量+缩点)
链接:http://poj.org/problem?id=3177 题意:有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走.现已有m条路,求至少要新建多少条路,使得任 ...
- POJ 3177 Redundant Paths 边双(重边)缩点
分析:边双缩点后,消环变树,然后答案就是所有叶子结点(即度为1的点)相连,为(sum+1)/2; 注:此题有坑,踩踩更健康,普通边双缩短默认没有无向图没有重边,但是这道题是有的 我们看,low数组是我 ...
- POJ 3352 Road Construction ; POJ 3177 Redundant Paths (双联通)
这两题好像是一样的,就是3177要去掉重边. 但是为什么要去重边呢??????我认为如果有重边的话,应该也要考虑在内才是. 这两题我用了求割边,在去掉割边,用DFS缩点. 有大神说用Tarjan,不过 ...
- POJ 3177 Redundant Paths POJ 3352 Road Construction(双连接)
POJ 3177 Redundant Paths POJ 3352 Road Construction 题目链接 题意:两题一样的.一份代码能交.给定一个连通无向图,问加几条边能使得图变成一个双连通图 ...
- tarjan算法求桥双连通分量 POJ 3177 Redundant Paths
POJ 3177 Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12598 Accept ...
- POJ - 3177 Redundant Paths (边双连通缩点)
题意:在一张图中最少可以添加几条边,使其中任意两点间都有两条不重复的路径(路径中任意一条边都不同). 分析:问题就是最少添加几条边,使其成为边双连通图.可以先将图中所有边双连通分量缩点,之后得到的就是 ...
- POJ 3177 Redundant Paths(边双连通的构造)
Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 13717 Accepted: 5824 ...
- poj 3177 Redundant Paths【求最少添加多少条边可以使图变成双连通图】【缩点后求入度为1的点个数】
Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11047 Accepted: 4725 ...
- poj 3177 Redundant Paths(tarjan边双连通)
题目链接:http://poj.org/problem?id=3177 题意:求最少加几条边使得没对点都有至少两条路互通. 题解:边双连通顾名思义,可以先求一下连通块显然连通块里的点都是双连通的,然后 ...
随机推荐
- Confluence 6 数据库整合的方法 2:针对有大量附件的运行实例
设置准备 这个方法仅仅针对附件存储在文件系统中.如果你存储附件在数据库中,请参考 Attachment Storage Configuration 文档中的内容来找到如何在 2 种不同的文件存储方式之 ...
- conda 安装多个版本的python
再添加一个python3.6conda create --name py36 python=3.6然后通过source activate py36来激活环境
- Hive shell 基本命令
首先连接 hive shell 直接输入 hive启动, 使用--开头的字符串来表示注释 hive>quit; --退出hive hive> exit; --exit会影响之前的使用,所以 ...
- Eclipse+maven+scala+spark环境搭建
准备条件 我用的Eclipse版本 Eclipse Java EE IDE for Web Developers. Version: Luna Release (4.4.0) 我用的是Eclipse ...
- 【linux】复制文件夹内容到另一个文件夹
我一直觉得cp是个非常简单的指令.结果居然遇到坑了.记录一下. 文件夹1:test1/ 文件夹2:test2/ 目标:将test1/中的所有文件和目录拷贝到test2/中 正确指令: cp -rf t ...
- 广工赛-hdu6468构造十叉树
是个以前没见过的模板题.. 我用比较复杂度方式过掉了.. 构造一个十叉树(有点trie的味道)来存数字,然后字典序就是先序遍历的结果 #include<bits/stdc++.h> usi ...
- Vue router拦截 如果用户并未登录直接跳转到登录界面(最简单的cookie演示)
router.beforeEach(function(to,from,next){ console.log('路由拦截') console.log(to.name) console.log(from. ...
- Python(文件操作实例)
给定一个文件:以及给定的字符,比如“a”; 统计字符个数:(可选) # 文件的打开操作f = open("wyl.txt","r")# 文件的读取操作conte ...
- Task任务的屏障机制
Barrier 是 .Net 提供的一直并发的机制,它允许多个任务同步他们不同阶段的并发工作. 这里的关键点是[多个任务]和[不同阶段]. 假设有4个相同的任务(Task),每个任务都有4个阶段(Ph ...
- 弹性和瞬态故障处理库Polly
介绍 本节我们来介绍一款强大的库Polly,Polly是一种.NET弹性和瞬态故障处理库,允许我们以非常顺畅和线程安全的方式来执诸如行重试,断路,超时,故障恢复等策略. Polly针对对.NET 4. ...