Warm up

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)

Total Submission(s): 3160    Accepted Submission(s): 718

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

题意:求出给定图中所有桥的数量,减去缩点后的最长链,即为题中所求答案(实际不用缩点也可求)

思路参考于:http://blog.csdn.net/qq172108805/article/details/9564705

#include "stdio.h"   //用到双连通分量和树形dp的思想
#include "string.h"
#pragma comment(linker,"/STACK:102400000,102400000") //手动扩大栈区(不扩栈会运行错误) #define N 201000
#define M 1001000 struct node
{
int x,y;
bool visit; //标记该边是否走过
int next;
}edge[4*M];
int idx,head[N]; inline int MIN(int a,int b){ return a<b?a:b; } void Init()
{
idx=0;
memset(head,-1,sizeof(head));
}
void Add(int x,int y)
{
edge[idx].x = x;
edge[idx].y = y;
edge[idx].visit = false; //开始时所有边都未走过
edge[idx].next = head[x];
head[x] = idx++;
} int n,m;
int sum,temp;
int low[N],dfn[N],time;
int dp1[N],dp2[N]; void DFS(int x)
{
int i,y;
dp1[x] = dp2[x] = 0;
low[x] = dfn[x] = ++time;
for(i=head[x]; i!=-1; i=edge[i].next)
{
if(edge[i].visit) continue;
y = edge[i].y;
edge[i].visit = edge[i^1].visit = true;
if(!dfn[y]) //点y未被访问过
{
DFS(y);
low[x] = MIN(low[x],low[y]);
if(low[y] > dfn[x])
sum++; //当前边为桥,sum++
temp = dp1[y];
if(low[y] > dfn[x])
temp++;
if(temp > dp1[x])
{
dp2[x] = dp1[x];
dp1[x] = temp;
}
else if(temp > dp2[x])
dp2[x] = temp;
}
else
low[x] = MIN(low[x],dfn[y]);
}
} int main()
{
int i;
int x,y;
while(scanf("%d %d",&n,&m),n||m)
{
Init();
for(i=0; i<m; ++i)
{
scanf("%d %d",&x,&y);
Add(x,y);
Add(y,x);
}
sum = 0; //统计图中桥的条数
time = 1;
memset(dfn,0,sizeof(dfn));
DFS(1);
int dist=0; //记录图的双连通分量缩点后的最长直径(最长的桥的长度)(实际不用处理缩点)
for(i=1; i<=n; ++i)
{
if(dist<dp1[i]+dp2[i]) //dp1[i]+dp2[i]为经过点i的最长路径的长度
dist = dp1[i]+dp2[i];
}
printf("%d\n",sum - dist);//所有桥的条数减最长路径的桥数,即为答案
}
return 0;
}

hdu 4612 Warm up 双连通+树形dp思想的更多相关文章

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

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

  2. HDU 2242 考研路茫茫—空调教室 (边双连通+树形DP)

    <题目链接> 题目大意: 给定一个连通图,每个点有点权,现在需要删除一条边,使得整张图分成两个连通块,问你删除这条边后,两联通块点权值和差值最小是多少. 解题分析: 删除一条边,使原连通图 ...

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

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

  4. HDU 2242 考研路茫茫——空调教室(边双连通分量+树形dp+重边标号)

    http://acm.hdu.edu.cn/showproblem.php?pid=2242 题意: 思路:首先求一下双连通分量,如果只有一个双连通分量,那么无论断哪根管子,图还是连通的. 最后只需要 ...

  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(2013多校2 1002 双连通分量)

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

  7. HDU 5739 Fantasia 双连通分量 树形DP

    题意: 给出一个无向图,每个顶点有一个权值\(w\),一个连通分量的权值为各个顶点的权值的乘积,一个图的权值为所有连通分量权值之和. 设删除顶点\(i\)后的图\(G_i\)的权值为\(z_i\),求 ...

  8. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  9. HDU 1520.Anniversary party 基础的树形dp

    Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

随机推荐

  1. PHP 简单处理--文件下载--文件上传

    文件下载部分 从 down 目录下下载,先获取目录下所有文件,再为每个文件添加download 信息,主要是文件名,后缀的关系. 分两部分,down_1.php 部分初始化,点击download 则跳 ...

  2. ok6410 android driver(3)

    This article discusses the Makefile and how to port the module to different platform (localhost and ...

  3. C#调用webservice 时如何传递实体对象

    在webservice端公开一个实体类,然后实例化,赋值,然后再给到webservice,可以实现,但是,即使调用端和service端的实体类完全一致,你也要重新实例化service端的,重新赋值,将 ...

  4. EasyUI中Base(基础)的基本用法

    EasyUI中Base(基础)的用法 一.Base(基础) 1.parser 解析器 2.easyloader 简单加载 3.draggable 拖动 4.droppable 放置 5.resizab ...

  5. sql:Oracle11g 表,视图,存储过程结构查询

    -- Oracle 11 G --20160921 涂聚文再次修改 --Geovin Du --GetTables SELECT owner, object_name, created FROM al ...

  6. 我的HTML笔记

    HTML(Hypertext Marked Language)"超文本标记语言". 1.HTML的声明 <!DOCTYPE html> 2.HTML的基本结构 < ...

  7. NYOJ:题目860 又见01背包

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=860 方法一:不用滚动数组(方法二为用滚动数组,为方法一的简化) 动态规划分析:最少要拿总 ...

  8. 优先队列(stl)

    优先队列是堆排的一种优化,我学习的是使用stl库的堆排. 基本操作有: 1.push将一个元素入队. 2.pop将一个元素出队. 3.top返还值为队头元素. 4.empty判断队列是否为空,为空返回 ...

  9. Javascript中void操作符

    Javascript中void是一个操作符,该操作符指定要计算一个表达式但是不返回值. void操作符用法格式如下:1.javascript:void (expression)2.javascript ...

  10. 【原创】使用.NET Core 1.0创建一个Self-Contained控制台应用

    开发机器:win7-x64 .NET Core版本:1.0.0-preview2-003121 Visual Studio Code:1.2.1 至于什么是Self-Contained应用类型以及与P ...