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条边的无向连通图(无自环,可能有重边).求添加一条边后最少剩余的桥的数 ...
随机推荐
- visionpro9.0破解
visionpro9.0软件下载 提供一个visionpro9.0视频教程学习网站:点击下面链接进入. ------------------------Halcon,Visionpro高清视频教程,点 ...
- 简单构建基于RDF和SPARQL的KBQA(知识图谱问答系统)
本文主要通过python实例讲解基于RDF和SPARQL的KBQA系统的构建.该项目可在python2和python3上运行通过. 注:KBQA即是我们通常所说的基于知识图谱的问答系统.这里简单构建的 ...
- 为什么安装beego和框架的失败 以及常用命令
1.安装了几个版本,版本之间相互影响. 把没用的删掉 2.网上找的教程存在问题. 都是相互抄袭.最权威的还是官网. which go rm -rf test/ echo path 获取路径 vim ~ ...
- php+原生ajax实现图片文件上传功能实例
html+js 代码 <!DOCTYPE html> <html> <head> <title>Html5 Ajax 上传文件</title> ...
- "Hello world!"团队第八次会议
Scrum会议 今天是我们"Hello world!"团队第八次召开会议,博客内容是: 1.会议时间 2.会议成员 3.会议地点 4.会议内容 5.todo list 6.会议照片 ...
- BluetoothDevice详解
一. BluetoothDevice简介 1. 继承关系 public static Class BluetoothDevice extends Object implement Parcelable ...
- <Android>日期,时间选择对话框
a) 调用Activity的onCreateDialog()方法创建对话框 b) 分别在OnDateSetListener的onDateSet()方法和OnTimeSet ...
- 【week3】词频统计 单元测试
使用Eclipse 集成的Junit进行单元测试.单元测试的核心包括断言.注解. 测试代码如下: @BeforeClass // 针对所有测试,只执行一次,且必须为static void public ...
- week1 技术随笔
类别c 内容c 开始时间s 结束时间e 被打断时间I 总计(min) 9.5 随笔 构建之法福后感 22:00 24:00 7 113 9.6 分析 需求分析 9:00 9:30 2 28 编码 词频 ...
- intellij idea 之 CheckStyle 代码格式校验