Redundant Paths-POJ3177(并查集+双连通分量)
Description
path and want to build some new paths so that they will always have a choice of at least two separate routes between any pair of fields. They currently have at least one route between each pair of fields and want to have at least two. Of course, they can only
travel on Official Paths when they move from one field to another.
Given a description of the current set of R (F-1 <= R <= 10,000) paths that each connect exactly two different fields, determine the minimum number of new paths (each of which connects exactly two fields) that must be built so that there are at least two separate
routes between any pair of fields. Routes are considered separate if they use none of the same paths, even if they visit the same intermediate field along the way.
There might already be more than one paths between the same pair of fields, and you may also build a new path that connects the same fields as some other path.
Input
Lines 2..R+1: Each line contains two space-separated integers which are the fields at the endpoints of some path.
Output
Sample Input
7 7
1 2
2 3
3 4
2 5
4 5
5 6
5 7
Sample Output
2
Hint
One visualization of the paths is:
1 2 3
+---+---+
| |
| |
6 +---+---+ 4
/ 5
/
/
7 +
Building new paths from 1 to 6 and from 4 to 7 satisfies the conditions.
1 2 3
+---+---+
: | |
: | |
6 +---+---+ 4
/ 5 :
/ :
/ :
7 + - - - -
Check some of the routes:
1 – 2: 1 –> 2 and 1 –> 6 –> 5 –> 2
1 – 4: 1 –> 2 –> 3 –> 4 and 1 –> 6 –> 5 –> 4
3 – 7: 3 –> 4 –> 7 and 3 –> 2 –> 5 –> 7
Every pair of fields is, in fact, connected by two routes.
It's possible that adding some other path will also solve the problem (like one from 6 to 7). Adding two paths, however, is the minimum.
Source
给定一个无向连通图,判断至少加多少的边,才能使任意两点之间至少有两条的独立的路(没有公共的边,但可以经过同一个中间的顶点)。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define LL long long using namespace std; const int MaxN = 10100; const int MaxM = 5100;
// 建图
typedef struct node
{
int v;
int next;
}Line; Line Li[MaxN*2]; int Belong[MaxM];//判断所属的双连通的集合
//回到最优先遍历度最小的节点和记录点DFS的顺序
int low[MaxM],dfn[MaxM]; int Head[MaxM],top; int pre[MaxM]; //并查集 int vis[MaxM],Num;//标记点的状态 int Bridge[MaxM][2],NumB;//记录图中的桥 void AddEdge(int u,int v)// 建边
{
Li[top].v=v; Li[top].next=Head[u];
Head[u]=top++; Li[top].v=u; Li[top].next=Head[v];
Head[v]=top++;
} int Find(int x)// 路径压缩
{
return pre[x]==-1?x:pre[x]=Find(pre[x]);
} void Union(int x,int y)
{
int Fx = Find(x); int Fy = Find(y); if(Fx!=Fy)
{
pre[Fx] = Fy;
}
} void dfs(int u,int father)
{
low[u]=dfn[u]=Num++; vis[u]=1;//表示已经遍历但是没有遍历完子女 for(int i=Head[u];i!=-1;i=Li[i].next)
{
int j=Li[i].v; if(vis[j]==1&&j!=father)// 回到的祖先
{
low[u]=min(low[u],dfn[j]);
}
if(vis[j]==0)
{
dfs(j,u); low[u]=min(low[j],low[u]); if(low[j]<=dfn[u])//说明是双连分量中的边
{
Union(u,j);
}
if(low[j]>dfn[u])//桥
{
Bridge[NumB][0]=j;
Bridge[NumB++][1]=u;
}
}
}
vis[u]=2;
} int main()
{
int n,m; while(~scanf("%d %d",&n,&m))
{ top=0; int u,v; memset(Head,-1,sizeof(Head)); memset(pre,-1,sizeof(pre));
for(int i=1;i<=m;i++)
{
scanf("%d %d",&u,&v); AddEdge(u,v);
} memset(vis,0,sizeof(vis)); memset(Belong ,-1 ,sizeof(Belong)); Num = 0 ; NumB=0 ; dfs(1,0); Num = 0;
for(int i=1;i<=n;i++)
{
int k=Find(i);//给双连通分量集合编号 if(Belong[k]==-1)
{
Belong[k]=++Num;
}
Belong[i]=Belong[k];
}
memset(vis,0,sizeof(vis)); for(int k=0;k<NumB;k++)
{
int i=Bridge[k][0]; int j=Bridge[k][1]; vis[Belong[i]]++; vis[Belong[j]]++;
} int ans = 0; for(int i=1;i<=n;i++)
{
if(vis[i]==1)
{
ans++;
}
}
printf("%d\n",(ans+1)/2);
}
return 0;
}
Redundant Paths-POJ3177(并查集+双连通分量)的更多相关文章
- POJ3177:Redundant Paths(并查集+桥)
Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 19316 Accepted: 8003 ...
- Redundant Paths POJ - 3177(边—双连通分量)
题意: 在图中加边 看最少能通过加多少条边把 图变成边—双连通分量 解析: 先做一次dfs,不同的连通分量的low是不同的 注意重边 缩点 统计度为1的点 那么需要加的边为(ret+1)/2 #i ...
- poj-3177(并查集+双联通分量+Tarjan算法)
题目链接:传送门 思路: 题目要将使每一对草场之间都有至少两条相互分离的路径,所以转化为(一个有桥的连通图至少加几条边才能变为双联通图?) 先求出所有的桥的个数,同时将不同区块收缩成一个点(利用并查集 ...
- HDU - 5438 Ponds(拓扑排序删点+并查集判断连通分量)
题目: 给出一个无向图,将图中度数小于等于1的点删掉,并删掉与他相连的点,直到不能在删为止,然后判断图中的各个连通分量,如果这个连通分量里边的点的个数是奇数,就把这些点的权值求和. 思路: 先用拓扑排 ...
- [HDU1232] 畅通工程 (并查集 or 连通分量)
Input 测试输入包含若干测试用例.每个测试用例的第1行给出两个正整数,分别是城镇数目N ( < 1000 )和道路数目M:随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的 ...
- poj3177重修道路——边双连通分量缩点
题目:http://poj.org/problem?id=3177 找桥,缩点,总之都是板子: 对于每个叶子,互相连一条边即可:若最后剩下一个,则去和根节点连边: 所以叶子节点数+1再/2即答案. 代 ...
- PAT Advanced A1021 Deepest Root (25) [图的遍历,DFS,计算连通分量的个数,BFS,并查集]
题目 A graph which is connected and acyclic can be considered a tree. The height of the tree depends o ...
- POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8807 Accepted ...
- 并查集(UVA 1106)
POINT: 把每个元素看成顶点,则一个简单化合物就是一条无向边,若存在环(即k对组合中有k种元素),则危险,不应该装箱,反之,装箱: 用一个并查集维护连通分量集合,每次得到一种化合物(x, y)时检 ...
随机推荐
- centos6.6 安装 LXC
LXC,简称Linux containers是docker基础,无奈只能先学习LXC.LXC用途就不多讲,这里只讲LXC的安装以及用途吧! LXC 需要用在内核2.6.27以上 这个可以用 uname ...
- 解决PHP下导出csv乱码小记
我们之前都是使用PHPexcel导出我们的一些数据的,由于Phpexcel对导出超出1万条数据会导至超时和内存暴涨,后来我们就改用数据导出成csv格式的. 相信很多朋友们在用PHP导出csv文件时都遇 ...
- Maven学习 (四) 使用Nexus搭建Maven私服
为什么要搭建nexus私服,原因很简单,有些公司都不提供外网给项目组人员,因此就不能使用maven访问远程的仓库地址,所以很有必要在局域网里找一台有外网权限的机器,搭建nexus私服,然后开发人员连到 ...
- BizTalk开发系列(三十三)BizTalk之Excel终极解决方案
Excel作为优秀的客户端数据处理程序得到了广泛的应用. 由于其简单又强大的功能在很多公司或个人的数据处理中占用非常重要的位置. 而BizTalk作为微软的SOA主打产品虽然免费提供了很多Adapte ...
- Struts2的Action(二)
Struts2的Action可以是一个POJO(即简单的javaBean),也实现Action接口,或者继承ActionSupport类. 1.Action接口: public interface A ...
- 【转】Eclipse 常用快捷键 (动画讲解)
Eclipse有强大的编辑功能, 工欲善其事,必先利其器, 掌握Eclipse快捷键,可以大大提高工作效率. 小坦克我花了一整天时间, 精选了一些常用的快捷键操作,并且精心录制了动画, 让你一看就会. ...
- Linux内存管理基本概念
1. 基本概念 1.1 地址 (1)逻辑地址:指由程序产生的与段相关的偏移地址部分.在C语言指针中,读取指针变量本身值(&操作),实际上这个值就是逻辑地址,它是相对于你当前进程数据段的地址.( ...
- Objective-C基础语法快速入门
Objective-C基础语法快速入门 2010-11-04 16:32 折酷吧 zheku8 字号:T | T 假如我们对面向对象的思维已经C语言都很熟悉的话,对于我们学习Objective-C将会 ...
- 资源绑定ResourceBundle
package com.init; import java.util.ResourceBundle; public class Resources { /** * @param args */ pub ...
- Fiddler-010-网络延时应用小技巧-模拟低网速环境
在日常的网络测试中,经常需要测试网络超时或在网络传输速率不佳的情况的应用场景,而与此同时我们有时手边资源有限,实现在各种真实网络(2G\3G)环境下测试有些局限性.其实 fiddler 已经提供了类似 ...