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条边的无向连通图(无自环,可能有重边).求添加一条边后最少剩余的桥的数 ...
随机推荐
- JavaScript 常用控制流程代码范例
if-else 的用法 var a = 33 if (a == 1){ console.log ('a等于1') } else if (a==2) { console.log ('a等于2') } e ...
- Python3 小工具-MAC泛洪
from scapy.all import * import optparse def attack(interface): pkt=Ether(src=RandMAC(),dst=RandMAC() ...
- Java内存管理特点
Java内存管理特点 Java一个最大的优点就是取消了指针,由垃圾收集器来自动管理内存的回收.程序员不需要通过调用函数来释放内存. 1.Java的内存管理就是对象的分配和释放问题. 在 ...
- html5 canvas绘制环形进度条,环形渐变色仪表图
html5 canvas绘制环形进度条,环形渐变色仪表图 在绘制圆环前,我们需要知道canvas arc() 方 ...
- Thunder团队第一周 - Scrum会议7
Scrum会议7 小组名称:Thunder 项目名称:爱阅app Scrum Master:宋雨 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传康 ...
- 初学c#(又要打代码了好难)
因为我原来从没有学过C#,所以要重新看一个语言的基本语法,仔细阅读了老师的作业要求,发现第一个10分的作业如果要用c语言写我是可以完成的,于是定个小目标就是在周日前完成作业的第一步.今天我在菜鸟教程的 ...
- 【week3】psp (技术随笔)
本周psp: 随笔字数: 总计 累计代码行 (前两项为单元测试部分) 词频统计:87 四则运算:49 四人小组:39 175 随笔字数 (不包含代码字数) 词频统计:237 四则运算:125 四人小组 ...
- HDU 2161 Primes
http://acm.hdu.edu.cn/showproblem.php?pid=2161 Problem Description Write a program to read in a list ...
- 相机上的P,S,A,M分别是什么单词的缩写?
程序曝光 Programmed Auto快门优先 Shutter Priority光圈优先 aperture-priority 全手动模式 Manual Mode
- C/S结构
C/S结构 编辑 同义词 C/S架构一般指C/S结构 C/S 结构,即大家熟知的客户机和服务器结构.它是软件系统体系结构,通过它可以充分利用两端硬件环境的优势,将任务合理分配到Client端和Serv ...