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)时检 ...
随机推荐
- javascript平时小例子④(setInterval使用2)
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>& ...
- c#...的类型初始值设定项引发异常。
今天一直遇到这个问题
- Bootstrap css背景图片的设置
一. 网页中添加图片的方式有两种 一种是:通过<img>标签直接插入到html中 另一种是:通过css背景属性添加 居中方法:水平居中的text-align:center 和 margin ...
- IOS第17天(1,Quartz2D图片水印)
****图片 水印 #import "HMViewController.h" @interface HMViewController () @property (weak, non ...
- mysql数据库、表、字段、记录:增、删、改、查
/* 结构:数据库.表.字段.记录 操作:增删改查 */ -- 1.数据库:增删改查 create datebase if not exists jkxy; drop database if exis ...
- js 除法 取整
js 除法 取整 1.丢弃小数部分,保留整数部分 js:parseInt(7/2) 2.向上取整,有小数就整数部分加1 js: Math.ceil(7/2) 3,四舍五入. js: Math.roun ...
- cocos2d-x场景切换动画
void StartScene::beginGame() { CCLog("beginGame"); //CCTransitionScene *trans ...
- 【整理】虚拟机和主机ping不通解决办法
检查几个方面: 1.检查虚拟网卡有没有被禁用2.检查虚拟机与物理机是否在一个VMNet中3.检查虚拟机的IP地址与物理机对应的VMNet是否在一个网段4.检查虚拟机与物理机的防火墙是否允许PING, ...
- iOS,文本输入,键盘相关
1.UIKeyboard键盘相关知识点 2.点击空白区域隐藏键盘(UIKeyboard) 3.键盘(UIKeyboard)挡住输入框处理 4.自定义键盘(UIKeyboard) 5.监听键盘弹出或消失 ...
- erlang httpc
1,set proxy 10.100.1.76 :8888 httpc:set_options([{proxy,{{"10.100.1.76",8888},[]}}]). 2,se ...