http://acm.hdu.edu.cn/showproblem.php?pid=4612

题目大意:求加一条边最小的桥数

先用Tarjin缩点求出一棵树,然后用bfs求出树的直径,树的直径就是加一条边桥最多的呢条边。

最后就用桥减去直径就行了

Warm up

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 5184    Accepted Submission(s): 1159

Problem 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<cstring>
#include<algorithm>
#include<iostream>
#include<stack>
#include<queue>
#include<cstdlib> using namespace std;
const int N=;
struct node
{
int next,to;
}edge[N*],Edge[N*];
int Stack[N],low[N],dfn[N],belong[N],sum,Time,top;
int Head[N],head[N],ans,Ans,Max,dis[N],vis[N],End; void Inn()
{
memset(Stack,,sizeof(Stack));
memset(low,,sizeof(low));
memset(dfn,,sizeof(dfn));
memset(Head,-,sizeof(Head));
memset(head,-,sizeof(head));
memset(belong,,sizeof(belong));
memset(dis,,sizeof(dis));
sum=Time=top=ans=Ans=Max=End=;
} void add(int from,int to)
{
edge[ans].to=to;
edge[ans].next=head[from];
head[from]=ans++;
} void Add(int from,int to)
{
Edge[Ans].to=to;
Edge[Ans].next=Head[from];
Head[from]=Ans++;
} void Tarjin(int u,int f)
{
int k=,v;
low[u]=dfn[u]=++Time;
Stack[top++]=u;
for(int i=head[u];i!=-;i=edge[i].next)
{
v=edge[i].to;
if(v==f && !k)
{
k++;
continue;
}
if(!dfn[v])
{
Tarjin(v,u);
low[u]=min(low[u],low[v]);
}
else
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
sum++;
do
{
v=Stack[--top];
belong[v]=sum;
}while(v!=u);
}
} void dfs(int s)
{
queue<int>Q;
int u,v;
memset(vis,,sizeof(vis));
dis[s]=;
vis[s]=;
Q.push(s);
while(Q.size())
{
u=Q.front();
Q.pop();
for(int i=Head[u];i!=-;i=Edge[i].next)
{
v=Edge[i].to;
if(!vis[v])
{
vis[v]=;
dis[v]=dis[u]+;
Q.push(v);
if(Max<dis[v])
{
Max=dis[v];
End=v;
}
}
}
}
} void slove(int n)
{
int SUM=;
Tarjin(,);
for(int i=;i<=n;i++)
{
for(int j=head[i];j!=-;j=edge[j].next)
{
int u=belong[i];
int v=belong[edge[j].to];
if(u!=v)
{
Add(u,v);
SUM++;
}
}
}
SUM/=;
dfs();
dfs(End);
printf("%d\n",SUM-Max);
}
int main()
{
int n,m,a,b;
while(scanf("%d %d",&n,&m),n+m)
{
Inn();
while(m--)
{
scanf("%d %d",&a,&b);
add(a,b);
add(b,a);
}
slove(n);
}
return ;
}

Warm up-HUD4612(树的直径+Tarjin缩点)的更多相关文章

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

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

  2. HDU 4612 Warm up tarjan 树的直径

    Warm up 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4612 Description N planets are connected by ...

  3. hdoj 4612 Warm up【双连通分量求桥&&缩点建新图求树的直径】

    Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Su ...

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

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

  5. HDU4612:Warm up(缩点+树的直径)

    Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Su ...

  6. HDU-4612 Warm up,tarjan求桥缩点再求树的直径!注意重边

    Warm up 虽然网上题解这么多,感觉写下来并不是跟别人竞争访问量的,而是证明自己从前努力过,以后回头复习参考! 题意:n个点由m条无向边连接,求加一条边后桥的最少数量. 思路:如标题,tarjan ...

  7. HDU4612 Warm up 边双(重边)缩点+树的直径

    题意:一个连通无向图,问你增加一条边后,让原图桥边最少 分析:先边双缩点,因为连通,所以消环变树,每一个树边都是桥,现在让你增加一条边,让桥变少(即形成环) 所以我们选择一条树上最长的路径,连接两端, ...

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

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

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

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

随机推荐

  1. 学习笔记 第十章 使用CSS美化表单

    第10章   使用CSS美化表单 [学习重点] 正确使用各种表单控件 熟悉HTML5新增的表单控件 掌握表单属性的设置 设计易用性表单页面 10.1  表单的基本结构 表单包含多个标签,由很多控件组成 ...

  2. CSS综合用法

    div 居中 {position: absolute; top: 50%; left: 50%; margin-top: -180px; margin-left: -160px;}

  3. Win7系统32位和64位的区别

    Win7系统32位和64位的区别已经是一个老话题了,可是还是有很多朋友不明白.这两者到底有什么区别呢?下面本文与大家通俗的介绍下Win7系统32位和64位的区别,其他一些深入的理论讲述,大家可以看看文 ...

  4. qt creator转换到 COFF 期间失败: 文件无效或损坏

    转载请注明出处http://www.cnblogs.com/dachen408/p/7226198.html 环境 Qt5.5+Vs2010,删除vs2010安装目录bin下的cvtres.exe解决 ...

  5. swal用法

    swal({   title: "确认删除?",   text: "Your will not be able to recover this imaginary fil ...

  6. leetcode_650. 2 Keys Keyboard_dp

    https://leetcode.com/problems/2-keys-keyboard/ 初始一个A,两种操作,复制当前所有A,粘贴,问得到n个A最少需要多少步操作. class Solution ...

  7. KMP中next数组的理解与应用

    理解 1.next数组一直往前走 next数组一直往前走,得到的所有前缀也是当前主串的后缀,当然了,也是当前主串的前缀. 2.周期性字符串 1.周期性字符串$\Leftrightarrow n \,\ ...

  8. Java基础(十一)--Serializable和Externalizable接口实现序列化

    序列化在日常开发中经常用到,特别是涉及到网络传输的时候,例如调用第三方接口,通过一个约定好的实体进行传输,这时你必须实现序列 化,这些都是大家都了解的内容,所以文章也会讲一下序列化的高级内容. 序列化 ...

  9. HTML location 用法(获取当前URL)

    Location 对象 Location 对象包含有关当前 URL 的信息. Location 对象是 Window 对象的一个部分,可通过 window.location 属性来访问. 属性 loc ...

  10. 制作framework&静态库

    http://blog.csdn.net/justinjing0612/article/details/7880712     (制作framework) http://blog.sina.com.c ...