题意:有N 个点,M条边,加一条边,求割边最少。(有重边)

分析:先求双连通分量,缩点形成一个生成树,然后求这个的直径,割边-直径即是答案

因为有的图上可能有重边,这样不好处理。我们记录每条边的标号(一条无向边拆成的两条有向边标号相同)这样就能限制不走一样的边而能走重边!

// File Name: 1002.cpp
// Author: Zlbing
// Created Time: 2013年08月02日 星期五 18时16分10秒
#pragma comment(linker,"/STACK:102400000,102400000")
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3f3f3f3f
#define LL long long
#define REP(i,r,n) for(int i=r;i<=n;i++)
#define RREP(i,n,r) for(int i=n;i>=r;i--)
const int MAXN=2e5+; int n,m;
struct Edge{
int u,v;
Edge(){}
Edge(int a,int b){
u=a;
v=b;
}
};
vector<Edge> edges;
vector<int> G[MAXN];
vector<int> P[MAXN];
int dfs_clock,bcc_cnt;
int pre[MAXN];
int T[MAXN];
//fa为u的父亲边
//这样标识就可以走重边而不能走父亲边
int dfs1(int u,int fa)
{
int lowu=pre[u]=++dfs_clock;
for(int i=;i<G[u].size();i++)
{
int mm=G[u][i];
int v=edges[mm].v;
if(fa==(mm^))continue;
if(!pre[v])
{
int lowv=dfs1(v,mm);
lowu=min(lowu,lowv);
if(lowv>pre[u])
{
P[v].push_back(u);
P[u].push_back(v);
}
}
else if(pre[v]<pre[u])
{
lowu=min(pre[v],lowu);
}
}
return lowu;
}
void dfs2(int u,int fa)
{
T[u]=bcc_cnt;
for(int i=;i<G[u].size();i++)
{
int v=edges[G[u][i]].v;
bool f=true;
for(int j=;j<P[u].size();j++)
{
int vv=P[u][j];
if(v==vv)
{
f=false;break;
}
}
if(!f||T[v])continue;
dfs2(v,u);
}
}
void find_bcc(int n)
{
dfs_clock=,bcc_cnt=;
memset(pre,,sizeof(pre));
memset(T,,sizeof(T));
for(int i=;i<=n;i++)
if(!pre[i])
dfs1(i,-);
for(int i=;i<=n;i++)
if(!T[i])
{
bcc_cnt++;
dfs2(i,-);
}
}
vector<int> GG[MAXN];
int d[MAXN];
void dfs(int u,int dep)
{
d[u]=dep;
for(int i=;i<GG[u].size();i++)
{
int v=GG[u][i];
if(!d[v])
{
dfs(v,dep+);
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n+m==)break;
REP(i,,n){
G[i].clear();
P[i].clear();
}
edges.clear();
int a,b;
REP(i,,m)
{
scanf("%d%d",&a,&b);
Edge e;
e=Edge(a,b);
edges.push_back(e);
e=Edge(b,a);
edges.push_back(e);
int mm=edges.size();
G[a].push_back(mm-);
G[b].push_back(mm-);
}
find_bcc(n);
REP(i,,n)
{
GG[i].clear();
}
/*
for(int i=1;i<=n;i++)
{
printf("T[%d]=%d\n",i,T[i]);
}
*/
for(int i=;i<=n;i++)
{
for(int j=;j<P[i].size();j++)
{
int v=P[i][j];
if(T[i]!=T[v])
{
// printf("u=%d v=%d\n",T[i],T[v]);
GG[T[i]].push_back(T[v]);
}
}
}
CL(d,);
dfs(,);
int maxn=;
int flag=;
for(int i=;i<=bcc_cnt;i++)
{
if(d[i]>maxn)
{
maxn=d[i];
flag=i;
}
}
CL(d,);
dfs(flag,);
maxn=;
for(int i=;i<=bcc_cnt;i++)
{
if(d[i]>maxn)
maxn=d[i];
}
// printf("bcc_cnt=%d maxn=%d\n",bcc_cnt,maxn);
cout<<bcc_cnt-maxn<<endl;
}
return ;
}

hdu-4612-Warm up(边双连通分量--有重边)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  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. hdu 4612 Warm up 双连通+树形dp思想

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

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

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

  10. HDU-4612 Warm up 边双连通分量+缩点+最长链

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612 简单图论题,先求图的边双连通分量,注意,此题有重边(admin还逗比的说没有重边),在用targ ...

随机推荐

  1. IOS的工程目录结构和生命周期

    IOS的工程目录结构和生命周期 ·simple table文件夹:工程相关源代码和配置文件 BIDAppDelegate :    委托的声明和实现 BIDViewController:    视图控 ...

  2. UICollectionView reloadData后cell被隐藏

    在使用UICollectionView的页面执行: [self.collectionView reloadData]; 执行后,页面变为空白页,调试发现,执行reloadData 后UICollect ...

  3. LINQ高级编程 笔记

    相关资料:http://www.cnblogs.com/lifepoem/archive/2011/12/16/2288017.html 1.什么是LINQ 语言集成查询是一系列标准查询操作符的集合, ...

  4. br与p标签区别

    首先,相同之处是br和p都是有换行的属性及意思其次,区别<br />是只需一个单独使用,而<p>和</p>是一对使用再次,br标签是小换行提行,p标签是大换行(分段 ...

  5. nopi导入导出

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  6. TOM大师脚本01-查找未建索引的外键

    [oracle@Oracle11g 2016]$ cat 022201.sql column columns format a30 word_wrappedcolumn tablename forma ...

  7. 移动端touchstar、touchmove、touchend 事件如果页面有滚动时不让触发 touchend 事件。

    /*仅适用于内容中点击元素.对于拖动等元素,需要自行在页面处理. * 主要是绑定touchstart和touchmove事件,并判断用户按下之后手指移动了多少像素. * 如果手指移动距离小于10像素, ...

  8. SGU 170.Particles

    Solution:               这其实是道很简单的题.               只要从一端开始,以‘+’或‘-’,任意一种开始找,找到与目标串最近的相同字符的距离就是需要交换的次数 ...

  9. Apache配置域名

    Apache配置域名 在WIN下安装APACHE配置虚拟目录和UNIN下基本是一样的就是修改httpd.conf1:单个IP对应单个域名例如:www.phpunion.com对应192.168.1.1 ...

  10. javascript为目标位置div等设置高度

    应该是DOM的东西: document.getElementById("目标id").style.height = 多高(数值)+"px";