HDU4612:Warm up(缩点+树的直径)
Warm up
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 9073 Accepted Submission(s): 2120
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612
Description:
N planets are connected by M bidirectional channels that allow instant transportation. It's always possible to travel between any two planets through these channels.
If we can isolate some planets from others by breaking only one channel , the channel is called a bridge of the transportation system.
People don't like to be isolated. So they ask what's the minimal number of bridges they can have if they decide to build a new channel.
Note that there could be more than one channel between two planets.
Input:
The input contains multiple cases.
Each case starts with two positive integers N and M , indicating the number of planets and the number of channels.
(2<=N<=200000, 1<=M<=1000000)
Next M lines each contains two positive integers A and B, indicating a channel between planet A and B in the system. Planets are numbered by 1..N.
A line with two integers '0' terminates the input.
Output:
For each case, output the minimal number of bridges after building a new channel in a line.
Sample Input:
4 4
1 2
1 3
1 4
2 3
0 0
Sample Output:
0
题意:
给出一个无向图,之后会加进来一条边,问加进来一条边过后,桥的最少数量为多少。
题解:
还是利用并查集先缩点,将无向图变为一颗树,树上每一条边都为桥。
然后加边我们希望尽量形成最大的环,那么考虑树的直径两端的点就满足了。
代码如下:
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
const int N = 2e5+,M = 1e6+;
int n,m;
int head[N];
struct Edge{
int u,v,next;
bool operator < (const Edge &A){
if(u==A.u) return v<A.v;
return u<A.u;
}
}e[M<<],g[M<<];
int T,tot,cnt;
int dfn[N],low[N],cut[N],num[N],f[N];
void adde(int u,int v){
e[tot].u=u;e[tot].v=v;e[tot].next=head[u];head[u]=tot++;
}
void init(){
T=;tot=;cnt=;
memset(head,-,sizeof(head));
memset(cut,,sizeof(cut));
memset(dfn,,sizeof(dfn));
memset(num,,sizeof(num));
for(int i=;i<=n+;i++) f[i]=i;
}
int find(int x){
return f[x]==x?f[x]:f[x]=find(f[x]);
}
void Union(int x,int y){
int fx=find(x),fy=find(y);
if(fx!=fy) f[fx]=fy;
}
void Tarjan(int u,int pre){
dfn[u]=low[u]=++T;
int k=;
for(int i=head[u];i!=-;i=e[i].next){
int v=e[i].v;
if(v==pre && !k){
k=;
continue ;
}
if(!dfn[v]){
Tarjan(v,u);
low[u]=min(low[u],low[v]);
}else{
low[u]=min(low[u],dfn[v]);
}
if(low[v]>dfn[u]){
cut[v]=;
}else Union(u,v);
}
}
int mx=,node=;
void dfs(int u,int d,int pa){
if(d>mx){
mx=d;
node=u;
}
for(int i=head[u];i!=-;i=e[i].next){
int v=e[i].v;
if(v==pa) continue ;
dfs(v,d+,u);
}
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
if(!n&&!m) break ;
init();
for(int i=;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
adde(u,v);adde(v,u);
if(u>v)swap(u,v);
g[i].u=u;g[i].v=v;
}
sort(g+,g+m+);
Tarjan(,);
memset(head,-,sizeof(head));tot=;
for(int i=;i<=m;i++){
int u=g[i].u,v=g[i].v;
if(g[i].u==g[i-].u&&g[i].v==g[i-].v) continue ;
int fx=find(u),fy=find(v);
if(!num[fx]) num[fx]=++cnt;
if(!num[fy]) num[fy]=++cnt;
if(num[fx]==num[fy]) continue ;
adde(num[fx],num[fy]);adde(num[fy],num[fx]);
}
mx=;
dfs(,,-);
mx=;
dfs(node,,-);
cout<<cnt--mx<<endl;
}
return ;
}
HDU4612:Warm up(缩点+树的直径)的更多相关文章
- hdu4612 Warm up 缩点+树的直径
题意抽象后为:给定一个无向图 问添加一条边的情况下最少能有多少个桥. 桥的定义:删除该边后原图变为多个连通块. 数据规模:点数N(2<=N<=200000),边数M(1<=M< ...
- HDU4612 Warm up 边双(重边)缩点+树的直径
题意:一个连通无向图,问你增加一条边后,让原图桥边最少 分析:先边双缩点,因为连通,所以消环变树,每一个树边都是桥,现在让你增加一条边,让桥变少(即形成环) 所以我们选择一条树上最长的路径,连接两端, ...
- hdu 4612 Warm up 有重边缩点+树的直径
题目链接 Warm up Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Tot ...
- hdu4612(双连通缩点+树的直径)
传送门:Warm up 题意:询问如何加一条边,使得剩下的桥的数目最少,输出数目. 分析:tarjan缩点后,重新建图得到一棵树,树上所有边都为桥,那么找出树的直径两个端点连上,必定减少的桥数量最多, ...
- hdu-4612(无向图缩点+树的直径)
题意:给你n个点和m条边的无向图,问你如果多加一条边的话,那么这个图最少的桥是什么 解题思路:无向图缩点和树的直径,用并查集缩点: #include<iostream> #include& ...
- HDU 4612 Warm up (边双连通分量+缩点+树的直径)
<题目链接> 题目大意:给出一个连通图,问你在这个连通图上加一条边,使该连通图的桥的数量最小,输出最少的桥的数量. 解题分析: 首先,通过Tarjan缩点,将该图缩成一颗树,树上的每个节点 ...
- F - Warm up HDU - 4612 tarjan缩点 + 树的直径 + 对tajan的再次理解
题目链接:https://vjudge.net/contest/67418#problem/F 题目大意:给你一个图,让你加一条边,使得原图中的桥尽可能的小.(谢谢梁学长的帮忙) 我对重边,tarja ...
- codeforces GYM 100114 J. Computer Network 无相图缩点+树的直径
题目链接: http://codeforces.com/gym/100114 Description The computer network of “Plunder & Flee Inc.” ...
- 【HDU 4612 Warm up】BCC 树的直径
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4612 题意:一个包含n个节点m条边的无向连通图(无自环,可能有重边).求添加一条边后最少剩余的桥的数 ...
随机推荐
- Laxcus大数据管理系统2.0(6)- 第四章 数据计算
第四章 数据计算 Laxcus所有数据计算工作都是通过网络实施.相较于集中计算,在网络间进行的数据计算更适合处理那些数据量大.复杂的.耗时长的计算任务.能够实施网络计算的前提是数据可以被分割,就是把一 ...
- error:no module named StringIO or cStringIO
一般遇到没有某个模块问题的时候,通常的解决方法是pip相应的模块: 不过,鉴于Python2和python3的不同(让人头疼) 解决方法:在python3中,该模块被新的模块取代,即io. 重新imp ...
- LeetCode - 13. Roman to Integer - 思考if-else与switch的比较 - ( C++ ) - 解题报告
1.题目: 原题:Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range ...
- linux下的常用技巧。
xargs linux下的多行合并~ [root@]# yum list installed|grep php|awk -F ' ' '{print $1}' php-channel-nrk.noa ...
- Bus of Characters(栈和队列)
In the Bus of Characters there are nn rows of seat, each having 22 seats. The width of both seats in ...
- Java学习个人备忘录之面向对象概念
对象,其实就是该类事物实实在在存在的个体. 类与对象之间的关系?类:一类事物的描述.对象:该类事物的实例.在java中通过new来创建的.举例来说,类就是汽车说明书,类只能在理论上造一辆汽车,并且这个 ...
- 20172330 2017-2018-1 《Java程序设计》第八周学习总结
学号 2017-2018-1 <程序设计与数据结构>第八周学习总结 教材学习内容总结 这一章主要是对多态性的学习: 由继承实现多态性 多态性引用能够随时间变化指向不同类型的对象. 对于多态 ...
- TCP系列02—连接管理—1、三次握手与四次挥手
一.TCP连接管理概述 正如我们在之前所说TCP是一个面向连接的通信协议,因此在进行数据传输前一般需要先建立连接(TFO除外),因此我们首先来介绍TCP的连接管理. 通常一次完整的TCP数据传输一般包 ...
- Zigbee安全基础篇Part.3
原文地址: https://www.4hou.com/wireless/14294.html 导语:在之前的文章中提供了ZigBee协议及其安全功能的简要概述.在本文中,我们将探讨可在ZigBee网络 ...
- centos7 下pycharm无法输入中文问题解决方案
作者使用的pycharm是2017.2 在pycharm.sh脚本的如下行(大约在201行): # -------------------------------------------------- ...