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, ...
随机推荐
- php webshell常见函数
0x1 直接在字符串变量后面加括号, 会调用这个函数: <?php $s = 'system'; $e = 'assert'; $s('whoami'); $e('phpinfo();'); 0 ...
- PHP7+Nginx的配置与安装教程详解
下面脚本之家小编把PHP7+Nginx的配置与安装教程分享给大家,供大家参考,本文写的不好还请见谅. 系统环境:centos6.5 x64 软件版本:nginx-1.10.0 php-7.0.6 安装 ...
- Linux中fork()函数的底层实现【转】
转自:http://blog.csdn.net/duoru_xiong/article/details/76358812 1. fork(),vfork(),clone()的区别 这三个系统调用的底层 ...
- C# 获取mp3文件的歌曲时间长度
添加命名空间: using Shell32; using System.Text.RegularExpressions;添加引用:COM组件的Microsoft Shell Control ...
- Centos更新配置文件命令
source 命令是 bash shell 的内置命令,从 C Shell 而来.source 命令的另一种写法是点符号,用法和 source 相同,从Bourne Shell而来.source 命令 ...
- Kaggle:Titanic: Machine Learning from Disaster
一直想着抓取股票的变化,偶然的机会在看股票数据抓取的博客看到了kaggle,然后看了看里面的题,感觉挺新颖的,就试了试. 题目如图:给了一个train.csv,现在预测test.csv里面的Passa ...
- CSU 1351 Tree Counting
原题链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1351 DP题,毫无疑问.由于动态规划题目做得少.不熟悉,刚开始自己用f[i]表示用 i ...
- 解决序列化类型为“System.Reflection.RuntimeModule”的对象时检测到循环引用。
定义一个继承JavaScriptConverter的子类 public class DataTableConverter : JavaScriptConverter { /// <summary ...
- [实战]MVC5+EF6+MySql企业网盘实战(5)——ajax方式注册
写在前面 今天贴合到实际的客户需求仔细的想了下,其实在userInfo这个类里面很多字段都不是必须的.有很多的事业单位根本就不能上网,填写的邮箱也是exchange的,个人的详细信息都在ad里面可以取 ...
- es6的set和get实现数据双向绑定,监听变量变化。
直接上代码吧,这个用法真的是效仿了.net的枚举. vue的数据双向绑定就是用这个实现的. 代码: html: <input type="text" id="inp ...