/**
题目大意:
给你一个无向连通图,问加上一条边后得到的图的最少的割边数; 算法思想:
图的边双连通Tarjan算法+树形DP;
即通过Tarjan算法对边双连通缩图,构成一棵树,然后用树形DP求最长链,连接首尾即可;剩下的连通块即为所求答案; 算法思路:
对图深度优先搜索,定义DFN(u)为u在搜索树中被遍历到的次序号;
定义Low(u)为u或u的子树中能通过非父子边追溯到的最早的节点,即DFN序号最小的节点;
则有:
Low(u)=Min
{
DFN(u),
Low(v),(u,v)为树枝边,u为v的父节点
DFN(v),(u,v)为指向栈中节点的后向边(非横叉边)
} 一个顶点u是割点,当且仅当满足(1)或(2)
(1)u为树根,且u有多于一个子树;
(2)u不为树根,且满足存在(u,v)为树枝边(或称父子边,即u为v在搜索树中的父亲),使得DFN(u)<=Low(v); 一条无向边(u,v)是桥,当且仅当(u,v)为树枝边且满足DFN(u)<Low(v); **/
#pragma comment(linker,"/STACK:102400000,102400000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<stack>
using namespace std; const int N=200010;
const int M=1000010; struct node
{
int v;
int next;
} e[M*2]; int head[N];
int dfn[N],low[N],dp[N][2];//dp[i][0]表示第i个节点的子树中最长的链,dp[i][1]表示第i个节点的子树中第二长的链
bool visit[M];
int n,m,cnt,res; void AddEdge(int u,int v)
{
e[cnt].v=v;
e[cnt].next=head[u];
head[u]=cnt++;
} void Tarjan(int u)
{
dfn[u]=low[u]=cnt++;
dp[u][0]=dp[u][1]=0;
for(int i=head[u]; i!=-1; i=e[i].next)
{
int j=e[i].v;
if(!visit[i>>1])
{
visit[i>>1]=true;
if(dfn[j]==0)//跟强连通一样
{
Tarjan(j);
res+=dfn[u]<low[j];//统计连通块,比实际数目少一个,就是回溯的时候的最后一个
int temp=dp[j][0]+(dfn[u]<low[j]);
if(temp>dp[u][0])
{
dp[u][1]=dp[u][0];
dp[u][0]=temp;
}
else if(temp>dp[u][1])
{
dp[u][1]=temp;
}
low[u]=min(low[u],low[j]);
}
else
low[u]=min(low[u],dfn[j]);
}
}
} int main()
{
#ifndef ONLINE_JUDGE
freopen("C:\\Users\\Administrator\\Desktop\\kd.txt","r",stdin);
#endif
while(scanf("%d%d",&n,&m)&&n+m)
{
cnt=0;
res=0;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(head,-1,sizeof(head));
for(int i=0; i<m; i++)
{
int u,v;
scanf("%d%d",&u,&v);
AddEdge(u,v);
AddEdge(v,u);
}
cnt=1;
memset(visit,0,sizeof(visit));
Tarjan(1);
int temp=0;
for(int i=1; i<=n; i++)
{
temp=max(temp,dp[i][0]+dp[i][1]);//+的时候没有算当前点所在的块,但是res也少算一个
}
printf("%d\n",res-temp);
}
return 0;
}

HDU4612(Warm up)2013多校2-图的边双连通问题(Tarjan算法+树形DP)的更多相关文章

  1. 图的强连通&双连通

    http://www.cnblogs.com/wenruo/p/4989425.html 强连通 强连通是指一个有向图中任意两点v1.v2间存在v1到v2的路径及v2到v1的路径. dfs遍历一个图, ...

  2. 图的割点 桥 双连通(byvoid)

    [点连通度与边连通度] 在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个连通块,就称这个点集为割点集合.一个图的点连通度的定义为,最小割点集 ...

  3. 图之强连通--Tarjan算法

    强连通分量 简介 在阅读下列内容之前,请务必了解图论基础部分. 强连通的定义是:有向图 G 强连通是指,G 中任意两个结点连通. 强连通分量(Strongly Connected Components ...

  4. 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 ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 网页上facebook分享功能的具体实现

    1,一个链接: 参数是要分享的页面的链接 代码如下: <a style="width:35px; height:40px; position:relative; top:10px; l ...

  2. oracle 分布式数据库

    分布式数据库的数据库链路是单向的

  3. Supervisor的一些基础使用

    Supervisor是一个进程监控程序. 满足的需求是:我现在有一个进程需要每时每刻不断的跑,但是这个进程又有可能由于各种原因有可能中断.当进程中断的时候我希望能自动重新启动它,此时,我就需要使用到了 ...

  4. Nginx源码研究一:NGINX模块启动

    Nginx 是一个轻量级,但是高性能的 HTTP 和 代理 服务器,也是一个 IMAP/POP3/SMTP代理服务器. 它的第一个版本0.1.0是由俄罗斯的工程师Igor Sysoev与2004年10 ...

  5. Android Framework------之ActivityManagerService与Activity之间的通信

    研究Android系统的童鞋,想必都已经了解一个Activity的启动过程了.而且在网上,关于Activity的启动的文章非常多,很容易就能找到的.这篇文章的重点放在ActivityManagerSe ...

  6. 简单代码JS随机,数组操作,延时执行

    <script language="javascript"> var str="baidu.com,163.com,sohu.com,kankan.com,1 ...

  7. 【结构型】Composite模式

    组合模式意在将对象组合成树形结构以表示部分与整体的层次结构关系,并且用户对单个对象的操作以有对组合对象的操作都是一致的.即:组合对象 is-a 单个对象,同时又可以组合着 n 个的单个对象(甚至于其他 ...

  8. AtomicInteger小小的理解

    这里仅仅是验证多线程环境下,AtomicInteger的安全性. 通过源码不难发现两点: 1.value属性是volatile修饰 2.使用了unsafe的CAS操作 通过上述两点,实现非阻塞同步(乐 ...

  9. c#使用UIA进行模拟点击操作

    之前,我写过一篇c#使用spy进行模拟操作的文章,有朋友在留言中提到了UIA进行操作,今天也使用UIA重新实现一次对vnc窗体的控制测试. 实现目标 在server框内填入192.168.2.200 ...

  10. ural 1126 Magnetic Storms

    http://acm.timus.ru/problem.aspx?space=1&num=1126 #include <cstdio> #include <cstring&g ...