Warm up

Time Limit:5000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u

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
 
 
题目大意:有n颗行星,有m条双向通道连接着m对行星。问你新建一条双向通道后,无向图中最少会剩下多少条桥。有重边。
 
解题思路:无向图求边双连通分量,缩点,重新构图,形成树。求树的直径,然后用原图总的桥减去树的直径即为结果。求树的直径,我们用两次搜索,第一次从任意点出发,搜到的最远结点即为直径的一端,然后从这一端再次进行搜索,搜到直径的另一端。
 
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
const int maxn = 200100;
struct Edge{
int from,to,dist,next;
Edge(){}
Edge(int _to,int _next):to(_to),next(_next){}
}edges[maxn*10];
int head[maxn], tot;
int dfs_clock, dfn[maxn], brinum;
int Stack[maxn], instack[maxn], top, ebccno[maxn], ebcc_cnt;
int deg[maxn];
vector<int>G[maxn];
void init(){
tot = 0;
brinum = dfs_clock = 0;
top = 0;
ebcc_cnt = 0;
memset(deg,0,sizeof(deg));
memset(head,-1,sizeof(head));
}
void AddEdge(int _u,int _v){
edges[tot] = Edge(_v,head[_u]);
head[_u] = tot++;
}
int dfs(int u,int fa){
int lowu = dfn[u] = ++dfs_clock;
Stack[++top] = u;
// instack[u] = 1;
for(int i = head[u]; i != -1; i = edges[i].next){
int v = edges[i].to;
if(!dfn[v]){
int lowv = dfs(v,i);
lowu = min(lowu,lowv);
if(lowv > dfn[u]){
brinum++;
}
}else if(dfn[v] < dfn[u] && (fa^1) != i){//这里用边的编号来标记是否是同一条边的回边
lowu = min(lowu,dfn[v]);
}
}
if(dfn[u] == lowu){ //找到一个边双连通分量
ebcc_cnt++;
for(;;){
int v = Stack[top--];
// instack[v] = 0;
ebccno[v] = ebcc_cnt; //给每个点划分一个分量标号
if(u == v){
break;
}
}
}
// low[u] = lowu;
return lowu;
}
void find_ebcc(int n){
memset(dfn,0,sizeof(dfn));
memset(instack,0,sizeof(instack));
for(int i = 1; i <= n; i++){
if(!dfn[i]){
dfs(i,-1);
}
}
}
int pos, Maxd;
void dfs1(int u,int dep,int fa){ //求树的直径
if(dep > Maxd){
Maxd = dep;
pos = u;
}
for(int i = 0; i < G[u].size(); i++){
int v = G[u][i];
if(fa == v){ continue; }
dfs1(v,dep+1,u);
}
}
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF&&(n+m)){
init();
for(int i = 0; i <= n; i++){
G[i].clear();
}
int a,b;
for(int i = 0; i < m; i++){
scanf("%d%d",&a,&b);
AddEdge(a,b);
AddEdge(b,a);
}
find_ebcc(n);
for(int i = 1; i <= n; i++){
for(int j = head[i]; j != -1; j = edges[j].next){
int v = edges[j].to;
if(ebccno[i] != ebccno[v]){ //重新构图,形成树
G[ebccno[i]].push_back(ebccno[v]);
}
}
}
pos = 1, Maxd = 0;
dfs1(1,0,-1);
int st = pos; Maxd = 0;
dfs1(pos,0,-1);
printf("%d\n",brinum - Maxd);
}
return 0;
}

  

 
 

HDU 4612——Warm up——————【边双连通分量、树的直径】的更多相关文章

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

    <题目链接> 题目大意:给出一个连通图,问你在这个连通图上加一条边,使该连通图的桥的数量最小,输出最少的桥的数量. 解题分析: 首先,通过Tarjan缩点,将该图缩成一颗树,树上的每个节点 ...

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

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

  3. HDU 4612 Warm up (边双连通分量+DP最长链)

    [题意]给定一个无向图,问在允许加一条边的情况下,最少的桥的个数 [思路]对图做一遍Tarjan找出桥,把双连通分量缩成一个点,这样原图就成了一棵树,树的每条边都是桥.然后在树中求最长链,这样在两端点 ...

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

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

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

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

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

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

  7. HDU 4612 Warm up(2013多校2 1002 双连通分量)

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

  8. [HDOJ4612]Warm up(双连通分量,缩点,树直径)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612 所有图论题都要往树上考虑 题意:给一张图,仅允许添加一条边,问能干掉的最多条桥有多少. 必须解决 ...

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

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

随机推荐

  1. Data Base mysql备份与恢复

    mysql  备份与恢复 为什么要备份: 由于系统使用到了MySQL 数 据库,所以每天的工作,就设计到了MySQL数据库的备份问题.但如果每天手工来做MySQL数据库的定时备份,工作量不说,时间还不 ...

  2. PCANet: A Simple Deep Learning Baseline for Image Classification?--名词解释

    1 上采样与下采样 缩小图像(或称为下采样(subsampled)或降采样(downsampled))的主要目的有两个: 使得图像符合显示区域的大小 生成对应图像的缩略图 下采样原理:对于一幅图像I尺 ...

  3. Android emulator中C代码的调试——gdb/gdbservers时遇到的坑

    版权声明:本文为博主原创文章,未经博主允许不得转载. 先写个helloworld吧,在Android源码树中创建文件夹external/helloworld,加入文件: // helloworld.c ...

  4. 2018沈阳网赛F--上下界网络流

    建图: 首先加一个源点s和汇点t,分别连接在二分图的左边和右边,每条弧的上下界为[L, R],二分图左边和右边之间连弧上下界为[0,1],其实就相当于连弧为1. 然后问题就转换为:有源汇最大流. 继续 ...

  5. thinkphp3.2.3 无法调用带下划线的模型

    thinkphp 3.2.3 如果表名中带有下划线,在分割的时候命名模型类,首字母大写,例如:order_customer_bom 为表名 .模型名为OrderCustomerBomModel 引用的 ...

  6. windwos下安装nginx(转)

    1.windows下安装Nginx1.1 从nginx官网下载相应的安装包:http://nginx.org/  1.2 建议下载  下载稳定版 1.3 解压到相应的目录,比如我是e盘 然后修改目录名 ...

  7. day-15递归与函数

    生成器send方法 send的工作原理 1.send发生信息给当前停止的yield 2.再去调用__next__()方法,生成器接着往下指向,返回下一个yield值并停止 # 案例: persons ...

  8. Common operators to overload-c++运算符重载的标准语法(全)

    Common operators to overload Most of the work in overloading operators is boiler-plate code. That is ...

  9. Leetcode 746. Min Cost Climbing Stairs 最小成本爬楼梯 (动态规划)

    题目翻译 有一个楼梯,第i阶用cost[i](非负)表示成本.现在你需要支付这些成本,可以一次走两阶也可以走一阶. 问从地面或者第一阶出发,怎么走成本最小. 测试样例 Input: cost = [1 ...

  10. PAT天梯赛 L1-049 天梯赛座位分配

    题目链接:点击打开链接 天梯赛每年有大量参赛队员,要保证同一所学校的所有队员都不能相邻,分配座位就成为一件比较麻烦的事情.为此我们制定如下策略:假设某赛场有 N 所学校参赛,第 i 所学校有 M[i] ...