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 树的直径的更多相关文章

  1. Hdu 4612 Warm up (双连通分支+树的直径)

    题目链接: Hdu 4612 Warm up 题目描述: 给一个无向连通图,问加上一条边后,桥的数目最少会有几个? 解题思路: 题目描述很清楚,题目也很裸,就是一眼看穿怎么做的,先求出来双连通分量,然 ...

  2. F - Warm up - hdu 4612(缩点+求树的直径)

    题意:有一个无向连通图,现在问添加一条边后最少还有几个桥 分析:先把图缩点,然后重构图为一棵树,求出来树的直径即可,不过注意会有重边,构树的时候注意一下 *********************** ...

  3. HDU 4612 Warm up tarjan缩环+求最长链

    Warm up Problem Description   N planets are connected by M bidirectional channels that allow instant ...

  4. HDU 4612 Warm up(Tarjan)

    果断对Tarjan不熟啊,Tarjan后缩点,求树上的最长路,注意重边的处理,借鉴宝哥的做法,开标记数组,标记自己的反向边. #pragma comment(linker, "/STACK: ...

  5. HDU 4612——Warm up——————【边双连通分量、树的直径】

    Warm up Time Limit:5000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  6. 【HDU 4612 Warm up】BCC 树的直径

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4612 题意:一个包含n个节点m条边的无向连通图(无自环,可能有重边).求添加一条边后最少剩余的桥的数 ...

  7. hdu 4612 Warm up 有重边缩点+树的直径

    题目链接 Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Tot ...

  8. 4612 warm up tarjan+bfs求树的直径(重边的强连通通分量)忘了写了,今天总结想起来了。

    问加一条边,最少可以剩下几个桥. 先双连通分量缩点,形成一颗树,然后求树的直径,就是减少的桥. 本题要处理重边的情况. 如果本来就两条重边,不能算是桥. 还会爆栈,只能C++交,手动加栈了 别人都是用 ...

  9. HDU 4612 Warm up(双连通分量缩点+求树的直径)

    思路:强连通分量缩点,建立一颗新的树,然后求树的最长直径,然后加上一条边能够去掉的桥数,就是直径的长度. 树的直径长度的求法:两次bfs可以求,第一次随便找一个点u,然后进行bfs搜到的最后一个点v, ...

随机推荐

  1. 【IDEA】与Eclipse "Link with Editor"等价功能设置

    Link With Editor是Eclipse内置功能中十分小巧,但却异常实用的一个功能.这个开关按钮 (Toggle Button) 出现在各式导航器视图 ( 例如 Resource Explor ...

  2. Supply

    Supplier创建一个Supply Supply有tap或emit方法. 可以这样理解: Supplier创建一个工厂 Supply 用tap创建流水线 emit向流水线上传送加工品进行加厂 my ...

  3. Linux中等待队列的实现

    1.       等待队列数据结构 等待队列由双向链表实现,其元素包括指向进程描述符的指针.每个等待队列都有一个等待队列头(wait queue head),等待队列头是一个类型为wait_quequ ...

  4. 72.Edit Distance---dp

    题目链接:https://leetcode.com/problems/edit-distance/description/ 题目大意:找出两个字符串之间的编辑距离(每次变化都只消耗一步). 法一(借鉴 ...

  5. 在Ubuntu上使用pip安装错误 read timed out 处理方法

    在终端输入 pip --default-timeout=1000 install -U pip 也就是修改超时时间.

  6. JavaWeb知识回顾-使用IDEA开发一个servlet.

    刚刚开始学习使用IDEA进行开发,好多都不会,本来想直接导入一个eclipse项目,但是出现了好多错误,一时不知道怎么修改,所以就从最基本的servlet开始着手,慢慢熟悉这个工具,下面是使用IDEA ...

  7. n*m的矩阵,行和列都递增有序,求是否出现target元素(面试题)

    题目描述:给定一个n*m的矩阵,矩阵的每一行都是递增的,每一列也是递增的,给定一个元素target,问该target是否在矩阵中出现. 思路:先从最左下角的元素开始找,三种情况: 1. 如果该元素大于 ...

  8. 记一次ceph集群的严重故障

    问题:集群状态,坏了一个盘,pg状态好像有点问题[root@ceph-1 ~]# ceph -s    cluster 72f44b06-b8d3-44cc-bb8b-2048f5b4acfe     ...

  9. 【WPF】Behavior的使用

    如何将一个行为附加到某个元素上呢?我们可以通过自定义一个Behavior! 我们首先看一下IAttachedObject接口,Behavior默认继承之这个接口 // 摘要: // 供可以附加到另一个 ...

  10. 【C#】IEnumrator的枚举数和IEnumerable接口

    声明IEnumerator的枚举数 要创建非泛型接口的枚举数,必须声明实现IEnumerator接口的类,IEnumerator接口有如下特性: 1.她是System.Collections命名空间的 ...