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



要求:树的直径+缩点

和上一道题纠结了好久,到底怎么加入一个块。

首先要明确边双连通分量和点双连通分量的区别与联系

1.二者都是基于无向图

2.边双连通分量是删边后还连通,而后者是删点

3.点双连通分量一定是边双连通分量(除两点一线的特殊情况),反之不一定,见HDU3749

4.点双连通分量可以有公共点,而边双连通分量不能有公共边

最后补充:

     点的双连通存桥(边),每访问一条边操作一次。 

            边的双连通存割点(点),访问完所有边后操作。

此题是边双连通,所以属于后者。yeah~~·

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int maxn=;
const int maxm=;
int Laxt[maxn],Next[maxm],To[maxm],cnt,vis[maxn];
int dfn[maxn],low[maxn];
int times,ans,cut_cnt,n,m;
int scc[maxn],scc_cnt;
int dis[maxn],S;
int stk[maxn],top,Maxdis,Maxpos;
vector<int>G[maxn];
void _init()
{
memset(Laxt,,sizeof(Laxt));
memset(dfn,,sizeof(dfn));
memset(scc,,sizeof(scc));
memset(vis,,sizeof(vis));
ans=cut_cnt=top=scc_cnt=cnt=times=;
}
void _add(int u,int v)
{
Next[++cnt]=Laxt[u];
Laxt[u]=cnt;
To[cnt]=v;
}
void _tarjan(int u,int v){
dfn[u]=low[u]=++times;
int num_v=;
stk[top++]=u;
for(int i=Laxt[u];i;i=Next[i]){
if(To[i]==v){
num_v++;
if(num_v==) continue;//保证重边
}
if(!dfn[To[i]]){
_tarjan(To[i],u);
if(low[u]>low[To[i]]) low[u]=low[To[i]];
if(dfn[u]<low[To[i]]) cut_cnt++;//割边,对应缩点后是边
}
else if(dfn[To[i]]<low[u]) low[u]=dfn[To[i]];
}
if(dfn[u]<=low[u]){//割点或者环里面第一个访问到的点(点连通缩点
G[++scc_cnt].clear();
for(;;){
int tmp=stk[--top];
scc[tmp]=scc_cnt;
if(tmp==u) break;
}
}
}
void _rebuild()//重建无环图
{
for(int i=;i<=n;i++)
for(int j=Laxt[i];j;j=Next[j])
if(scc[i]!=scc[To[j]])
G[scc[i]].push_back(scc[To[j]]);
}
void _dfs(int u)
{
int i,L=G[u].size();
for(int i=;i<L;i++)
if(!dis[G[u][i]]){
dis[G[u][i]]=dis[u]+;
_dfs(G[u][i]);
}
}
void _findR()
{
memset(dis,,sizeof(dis));
dis[]=;S=;Maxdis=;
_dfs();
for(int i=;i<=scc_cnt;i++)
if(dis[i]>dis[S]) S=i;
memset(dis,,sizeof(dis));
dis[S]=;
_dfs(S);
for(int i=;i<=scc_cnt;i++)
if(dis[i]>Maxdis) Maxdis=dis[i];
Maxdis--;
}
int main()
{
int i,j,k,u,v;
while(~scanf("%d%d",&n,&m)){
if(n==&&m==) return ;
_init();
for(i=;i<=m;i++){
scanf("%d%d",&u,&v);
_add(u,v);
_add(v,u);
}
for(i=;i<=n;i++)
if(!dfn[i]) _tarjan(i,-);
_rebuild();
_findR();
printf("%d\n",cut_cnt-Maxdis);
}
return ;
}

HDU4612Warm up 边双连通 Tarjan缩点的更多相关文章

  1. poj3352Road Construction 边双连通+伪缩点

    /* 对于边双连通分支,求法更为简单. 仅仅需在求出全部的桥以后,把桥边删除.\ 原图变成了多个连通块,则每一个连通块就是一个边双连通分支. 桥不属于不论什么 一个边双连通分支,其余的边和每一个顶点都 ...

  2. 图论--边双连通V-DCC缩点

    // tarjan算法求无向图的割点.点双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...

  3. 图论--双连通E-DCC缩点模板

    // tarjan算法求无向图的桥.边双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...

  4. HDU4612(Warm up)2013多校2-图的边双连通问题(Tarjan算法+树形DP)

    /** 题目大意: 给你一个无向连通图,问加上一条边后得到的图的最少的割边数; 算法思想: 图的边双连通Tarjan算法+树形DP; 即通过Tarjan算法对边双连通缩图,构成一棵树,然后用树形DP求 ...

  5. POJ-3352 Road Construction,tarjan缩点求边双连通!

    Road Construction 本来不想做这个题,下午总结的时候发现自己花了一周的时间学连通图却连什么是边双连通不清楚,于是百度了一下相关内容,原来就是一个点到另一个至少有两条不同的路. 题意:给 ...

  6. hdu 4612 Warm up 双连通缩点+树的直径

    首先双连通缩点建立新图(顺带求原图的总的桥数,事实上因为原图是一个强连通图,所以桥就等于缩点后的边) 此时得到的图类似树结构,对于新图求一次直径,也就是最长链. 我们新建的边就一定是连接这条最长链的首 ...

  7. POJ 3177 Redundant Paths (边双连通+缩点)

    <题目链接> <转载于 >>>  > 题目大意: 有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走.现已有m条路,求至少要新 ...

  8. POJ - 3177 Redundant Paths (边双连通缩点)

    题意:在一张图中最少可以添加几条边,使其中任意两点间都有两条不重复的路径(路径中任意一条边都不同). 分析:问题就是最少添加几条边,使其成为边双连通图.可以先将图中所有边双连通分量缩点,之后得到的就是 ...

  9. tarjan算法与无向图的连通性(割点,桥,双连通分量,缩点)

    基本概念 给定无向连通图G = (V, E)割点:对于x∈V,从图中删去节点x以及所有与x关联的边之后,G分裂为两个或两个以上不相连的子图,则称x为割点割边(桥)若对于e∈E,从图中删去边e之后,G分 ...

随机推荐

  1. 解题报告:hdu 1276 士兵队列训练问题 - 简单题

    Problem Description 某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行 ...

  2. java -jar 启动jar包 带参数

    运行jar包时指定端口:java -jar xxx.jar --server.port=8088 server.port=8081 若命令行传入的server.port没有作用,服务仍然使用8081端 ...

  3. 【转】R语言知识体系概览

    摘要:R语言的知识体系并非语法这么简单,如果都不了R的全貌,何谈学好R语言呢.本文将展示介绍R语言的知识体系结构,并告诉读者如何才能高效地学习R语言. 最近遇到很多的程序员都想转行到数据分析,于是就开 ...

  4. 谈一谈最近关闭的Kindle人论坛

    最近Kindle圈子内最大的论坛“Kindle人”关闭了,倒也掀起了一阵小波澜.Kindle人论坛是K友圈子里比较著名的一个“Kindle资源分享论坛”,这么一说其实混了这么久网络,大家都知道这个论坛 ...

  5. 百度地图API学习总结

    常用技术   1.创建地图: var map = new BMap.Map("divid"); 2.创建坐标点:var point = new BMap.Point("经 ...

  6. 第八天 1-7 实战:创建一个root无法删除的文件

    实战:创建一个root无法删除的文件 简介:Linux文件的最底层(内核级别)属性的查看与修改 命令:lsattr.chattr Linux文件除了具有基本权限rwx,及特殊权限(SUID.SGID. ...

  7. IOS-第三方开源库

    我找的琐碎框架 1.HZExtend:应用快速开发架构集合了MVC和MVVM的特点https://github.com/GeniusBrother/HZExtend : 1.减少控制器压力以及耦合 2 ...

  8. 【Windows】netsh动态配置端口转发

    文章转载自傲风 使用多个虚拟机,将开发环境和工作沟通环境分开(即时通,办公系统都只能在windows下使用-),将开发环境的服务提供给外部访问时,需要在主机上通过代理配置数据转发. VirtualBo ...

  9. cacti安装和使用

    关闭selinux 1.搭建lamp环境 配置apache [root@cacti-server ~]# yum -y install httpd [root@cacti-server ~]# sys ...

  10. [转载]Java在线打开PDF文档

    步骤一:(涉及到的工具) 访问:http://www.zhuozhengsoft.com/dowm/,从官网下载PageOffice for Java. 步骤二:(配置工程) 1. 解压PageOff ...