Warm up

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

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
 
Source
 
Recommend
zhuyuanchen520
 

问加一条边,最少可以剩下几个桥。

先双连通分量缩点,形成一颗树,然后求树的直径,就是减少的桥。

本题要处理重边的情况。

如果本来就两条重边,不能算是桥。

还会爆栈,只能C++交,手动加栈了

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
using namespace std; const int MAXN = ;//点数
const int MAXM = ;//边数,因为是无向图,所以这个值要*2 struct Edge
{
int to,next;
bool cut;//是否是桥标记
bool cong;
}edge[MAXM];
int head[MAXN],tot;
int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];//Belong数组的值是1~block
int Index,top;
int block;//边双连通块数
bool Instack[MAXN];
int bridge;//桥的数目 void addedge(int u,int v,bool pp)
{
edge[tot].to = v;edge[tot].next = head[u];edge[tot].cut=false;
edge[tot].cong = pp;
head[u] = tot++;
} void Tarjan(int u,int pre,bool ff)
{
int v;
Low[u] = DFN[u] = ++Index;
Stack[top++] = u;
Instack[u] = true;
for(int i = head[u];i != -;i = edge[i].next)
{
v = edge[i].to;
if(v == pre && (!ff))continue;
if( !DFN[v] )
{
Tarjan(v,u,edge[i].cong);
if( Low[u] > Low[v] )Low[u] = Low[v];
if(Low[v] > DFN[u])
{
bridge++;
edge[i].cut = true;
edge[i^].cut = true;
}
}
else if( Instack[v] && Low[u] > DFN[v] )
Low[u] = DFN[v];
}
if(Low[u] == DFN[u])
{
block++;
do
{
v = Stack[--top];
Instack[v] = false;
Belong[v] = block;
}
while( v!=u );
}
}
void init()
{
tot = ;
memset(head,-,sizeof(head));
} int du[MAXN];//缩点后形成树,每个点的度数
vector<int>vec[MAXN];
int dep[MAXN];
void dfs(int u)
{
for(int i = ;i < vec[u].size();i++)
{
int v = vec[u][i];
if(dep[v]!=-)continue;
dep[v]=dep[u]+;
dfs(v);
}
}
void solve(int n)
{
memset(DFN,,sizeof(DFN));
memset(Instack,false,sizeof(Instack));
Index = top = block = ;
Tarjan(,,false);
for(int i = ;i <= block;i++)
vec[i].clear();
for(int i = ;i <= n;i++)
for(int j = head[i];j != -;j = edge[j].next)
if(edge[j].cut)
{
vec[Belong[i]].push_back(Belong[edge[j].to]);
}
memset(dep,-,sizeof(dep));
dep[]=;
dfs();
int k = ;
for(int i = ;i <= block;i++)
if(dep[i]>dep[k])
k = i;
memset(dep,-,sizeof(dep));
dep[k]=;
dfs(k);
int ans = ;
for(int i = ;i <= block;i++)
ans = max(ans,dep[i]);
printf("%d\n",block--ans);
}
struct NN
{
int u,v;
}node[MAXM];
bool cmp(NN a,NN b)
{
if(a.u != b.u)return a.u<b.u;
else return a.v<b.v;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,m;
int u,v;
while(scanf("%d%d",&n,&m)==)
{
if(n== && m==)break;
init();
for(int i = ;i < m;i++)
{
scanf("%d%d",&u,&v);
if(u==v)continue;
if(u>v)swap(u,v);
node[i].u = u;
node[i].v = v;
}
sort(node,node+m,cmp);
for(int i = ;i < m;i++)
{
if(i == || (node[i].u!=node[i-].u || node[i].v != node[i-].v))
{
if(i < m- && (node[i].u==node[i+].u && node[i].v == node[i+].v))
{
addedge(node[i].u,node[i].v,true);
addedge(node[i].v,node[i].u,true);
}
else
{
addedge(node[i].u,node[i].v,false);
addedge(node[i].v,node[i].u,false);
}
}
}
solve(n);
}
return ;
}

HDU 4612 Warm up(2013多校2 1002 双连通分量)的更多相关文章

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

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

  2. HDU 4667 Building Fence(2013多校7 1002题 计算几何,凸包,圆和三角形)

    Building Fence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)To ...

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

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

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

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

  5. HDU 4705 Y (2013多校10,1010题,简单树形DP)

    Y Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submiss ...

  6. HDU 4704 Sum (2013多校10,1009题)

    Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submi ...

  7. HDU 4699 Editor (2013多校10,1004题)

    Editor Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Su ...

  8. HDU 4696 Answers (2013多校10,1001题 )

    Answers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total S ...

  9. HDU 4690 EBCDIC (2013多校 1005题 胡搞题)

    EBCDIC Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)Total Su ...

随机推荐

  1. Linux进程控制(二)

    1. 进程的创建 Linux下有四类创建子进程的函数:system(),fork(),exec*(),popen() 1.1. system函数 原型: #include <stdlib.h&g ...

  2. 单点登录系统构建之一——基础知识(Kerberous/SAML)

    http://web.mit.edu/kerberos/ Kerberos Kerberous是一个网络身份验证协议,它被设计为客户端/服务器提供基于密钥的强加密机制.该协议最初由MIT实现并被广泛商 ...

  3. Asp.Net验证码1

    验证码html调用 验证码:<input name="> <img src="CodeHandler.ashx" id="imgCode&qu ...

  4. 01.C语言关于结构体的学习笔记

    我对于学习的C语言的结构体做一个小的学习总结,总结如下: 结构体:structure 结构体是一种用户自己建立的数据类型,由不同类型数据组成的组合型的数据结构.在其他高级语言中称为记录(record) ...

  5. qt多文档

    http://blog.csdn.net/siren0203/article/details/5661541

  6. 【英语】Bingo口语笔记(19) - 如何用英语叙旧

  7. Android View绘制13问13答

    1.View的绘制流程分几步,从哪开始?哪个过程结束以后能看到view? 答:从ViewRoot的performTraversals开始,经过measure,layout,draw 三个流程.draw ...

  8. concat、reverse面试题

    1.concat数组连接 ,,]; ,,]; ,,]; alert(arr3.concat(arr1,arr2)); 结果:9,9,9,2,3,4,5,6,7 2.reverse将数组内容颠个个 ,, ...

  9. Web开发基础

    一.后台 1.MyEclipse:Java Web的编辑器 2.Java Servlet:后台代码 3.Velocity:前后台接口 4.mySql:数据库 二.前台 1.js:前台代码 2.jQue ...

  10. ArcGlobe点击IGlobeServerLayer图层读取信息

    ArcGISServer将点图层发布成Globe服务,AE开发中自定义识别工具,读取点数据信息. 1) 通过Locate方法获取图层对象,图层对象中的SearchOID就是你点中的要素Objectid ...