HDU 4612 Warm up tarjan 树的直径
Warm up
题目连接:
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
Hint
题意
让你加一条边,使得这个图的桥数量最小
输出桥的数量
题解:
先缩点,然后求一个直径,然后输出树边数减去直径就好了
这样显然最小
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 200000 + 500;
struct edge{
int v , nxt;
}e[2005000];
int head[maxn] , tot , n , m , dfn[maxn] , low[maxn] , dfs_clock , bridge , dis[maxn] , vis[maxn] , Ftp , belong[maxn] ;
stack < int > sp;
vector < int > G[maxn];
void link(int u , int v){ e[tot].v=v,e[tot].nxt=head[u],head[u]=tot++;}
void dfs(int x , int pre){
dfn[x] = low[x] = ++ dfs_clock; sp.push( x );
for(int i = head[x] ; ~i ; i = e[i].nxt ){
if( (i ^ 1) == pre ) continue;
int v = e[i].v;
if(!dfn[v]){
dfs( v , i );
low[x] = min( low[x] , low[ v ] );
if(low[v] > dfn[x]) bridge ++ ;
}else low[x]=min(low[x],dfn[v]);
}
if( low[x] == dfn[x] ){
++ Ftp;
while(1){
int u = sp.top() ; sp.pop();
belong[u] = Ftp;
if( u == x ) break;
}
}
}
queue < int > Q;
int solve(){
vis[1] = 1 ;
Q.push( 1 );
while(!Q.empty()){
int s = Q.front() ; Q.pop();
for(auto it : G[s]){
if( vis[it] == 0 ){
vis[it] = 1 ;
dis[it] = dis[s] + 1;
Q.push( it );
}
}
}
int s = -1 , index = 0;
for( int it = 1 ; it <= Ftp ; ++ it ){
if(dis[it] > s){
s = dis[it];
index = it;
}
}
for(int i = 1 ; i <= Ftp ; ++ i) dis[i] = vis[i] = 0;
Q.push( index );
vis[index] = 1;
while(!Q.empty()){
int s = Q.front() ; Q.pop();
for(auto it : G[s]){
if( vis[it] == 0 ){
vis[it] = 1 ;
dis[it] = dis[s] + 1;
Q.push( it );
}
}
}
s = 0;
for( int it = 1 ; it <= Ftp ; ++ it ){
if(dis[it] > s){
s = dis[it];
}
}
return s;
}
int main(int argc,char *argv[]){
while(scanf("%d%d",&n,&m)){
if( n == 0 && m == 0 ) break;
for(int i = 1 ; i <= n ; ++ i) head[i] = -1 , dfn[i] = low[i] = vis[i] = dis[i] = 0 , G[i].clear();
tot = dfs_clock = bridge = Ftp = 0 ;
for(int i = 1 ; i <= m ; ++ i){
int u , v ;
scanf("%d%d",&u,&v);
link( u , v );
link( v , u );
}
for(int i = 1 ; i <= n ; ++ i) if(!dfn[i]) dfs( i , 1 << 30 );
for(int i = 1 ; i <= n ; ++ i)
for(int j = head[i] ; ~j ; j = e[j].nxt){
int v = e[j].v;
if(belong[i] == belong[v]) continue;
G[belong[i]].push_back( belong[v] );
G[belong[v]].push_back( belong[i] );
}
int maxv = solve();
printf("%d\n" , bridge - maxv );
}
return 0;
}
HDU 4612 Warm up tarjan 树的直径的更多相关文章
- Hdu 4612 Warm up (双连通分支+树的直径)
题目链接: Hdu 4612 Warm up 题目描述: 给一个无向连通图,问加上一条边后,桥的数目最少会有几个? 解题思路: 题目描述很清楚,题目也很裸,就是一眼看穿怎么做的,先求出来双连通分量,然 ...
- F - Warm up - hdu 4612(缩点+求树的直径)
题意:有一个无向连通图,现在问添加一条边后最少还有几个桥 分析:先把图缩点,然后重构图为一棵树,求出来树的直径即可,不过注意会有重边,构树的时候注意一下 *********************** ...
- HDU 4612 Warm up tarjan缩环+求最长链
Warm up Problem Description N planets are connected by M bidirectional channels that allow instant ...
- HDU 4612 Warm up(Tarjan)
果断对Tarjan不熟啊,Tarjan后缩点,求树上的最长路,注意重边的处理,借鉴宝哥的做法,开标记数组,标记自己的反向边. #pragma comment(linker, "/STACK: ...
- HDU 4612——Warm up——————【边双连通分量、树的直径】
Warm up Time Limit:5000MS Memory Limit:65535KB 64bit IO Format:%I64d & %I64u Submit Stat ...
- 【HDU 4612 Warm up】BCC 树的直径
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4612 题意:一个包含n个节点m条边的无向连通图(无自环,可能有重边).求添加一条边后最少剩余的桥的数 ...
- hdu 4612 Warm up 有重边缩点+树的直径
题目链接 Warm up Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Tot ...
- 4612 warm up tarjan+bfs求树的直径(重边的强连通通分量)忘了写了,今天总结想起来了。
问加一条边,最少可以剩下几个桥. 先双连通分量缩点,形成一颗树,然后求树的直径,就是减少的桥. 本题要处理重边的情况. 如果本来就两条重边,不能算是桥. 还会爆栈,只能C++交,手动加栈了 别人都是用 ...
- HDU 4612 Warm up(双连通分量缩点+求树的直径)
思路:强连通分量缩点,建立一颗新的树,然后求树的最长直径,然后加上一条边能够去掉的桥数,就是直径的长度. 树的直径长度的求法:两次bfs可以求,第一次随便找一个点u,然后进行bfs搜到的最后一个点v, ...
随机推荐
- ogg使用语句
create tablespace ogg datafile '/oracle/oradata/DRMT/ogg01.dbf' size 50M autoextend on; edit params ...
- python设计模式之单例模式(一)
前言 单例模式是创建模式中比较常见和常用的模式,在程序执行的整个生命周期只存在一个实例对象. 系列文章 python设计模式之单例模式(一) python设计模式之常用创建模式总结(二) python ...
- linux下的僵尸进程处理SIGCHLD信号【转】
转自:http://www.cnblogs.com/wuchanming/p/4020463.html 什么是僵尸进程? 首先内核会释放终止进程(调用了exit系统调用)所使用的所有存储区,关闭所有打 ...
- elk系列7之通过grok分析apache日志【转】
preface 说道分析日志,我们知道的采集方式有2种: 通过grok在logstash的filter里面过滤匹配. logstash --> redis --> python(py脚本过 ...
- openjudge-NOI 2.6-2000 最长公共子上升序列
题目链接:http://noi.openjudge.cn/ch0206/2000/ 题解: 裸题,不解释(题目有毒) #include<cstdio> #include<algori ...
- tyvj P1050 最长公共子序列
题目链接:http://tyvj.cn/p/1050 题解: 裸题,只是为了测试LCS模板写对没有…… #include<cstdio> #include<cstring> # ...
- [转载]FFmpeg完美入门[1] - FFmpeg介绍及安装
1 FFmpeg简介 FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件).它提供了录制.转换以及流化音视 频的完整解决方案.它包含了非常先 ...
- [转载]锁无关的(Lock-Free)数据结构
锁无关的(Lock-Free)数据结构 在避免死锁的同时确保线程继续 Andrei Alexandrescu 刘未鹏 译 Andrei Alexandrescu是华盛顿大学计算机科学系的在读研究生,也 ...
- 三、ansible简要使用
1.ansible服务器生成公钥与私钥 ssh-keygen -t rsa 2.拷贝ansible公钥到客户机上 ssh-copy-id -i root@192.168.1.1 3.添加主机到ansi ...
- Hadoop(五)分布式集群中HDFS系统的各种角色
NameNode 学习目标 理解 namenode 的工作机制尤其是元数据管理机制,以增强对 HDFS 工作原理的 理解,及培养 hadoop 集群运营中“性能调优”.“namenode”故障问题的分 ...