题意:有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. shell入门之流程控制语句 分类: 学习笔记 linux ubuntu 2015-07-10 16:38 89人阅读 评论(0) 收藏

    1.case 脚本: #!/bin/bash #a test about case case $1 in "lenve") echo "input lenve" ...

  2. 最近的两个小项目,2:Python webapp的docker镜像

    时间过得真快,一眨眼一个多月没更新了,但这一个月我可没偷懒啊,真的是忙.粘上两篇ReadMe勉强凑合一下,保持博客更新是好习惯. 基于Flask框架,uwsgi起服务,supervisor做管理,应该 ...

  3. php三个执行命令函数

    今天第一次知道php也可以执行window命令: exec system echo ``  两个是反的单引号 通过个人测试是可以的,貌似只能在本地

  4. foreach遍历----for(object o: list)

    备注,两种写法是一样的.

  5. c#迭代算法

    //用迭代算法算出第m个值 //1,1,2,3,5,8...;           //{1,0+1,1+1,1+2,2+3 ,3+5} static void Main(string[]   arg ...

  6. Ubuntu系统中安装RPM格式包的方法

    Ubuntu的软件包格式为deb,而RPM格式的包则是Red Hat 相关系统所用的软件包.当我们看到一个想用的软件包时,如果他是RPM格式,而你的操作系统是Ubuntu,那岂不是很遗憾?其实,在Ub ...

  7. Oracle 10G强大的SQL优化工具:SQL Tuning Advisor

    p { margin-bottom: 0.25cm; direction: ltr; color: rgb(0, 0, 0); line-height: 120%; orphans: 2; widow ...

  8. iOS、mac开源项目及库汇总

    原文地址:http://blog.csdn.net/qq_26359763/article/details/51076499    iOS每日一记------------之 中级完美大整理 iOS.m ...

  9. 读书笔记之 - javascript 设计模式 - 单体模式

    单体是一个用来划分命名空间,并将一批相关方法和属性组织在一起的对象,如果它可以被实例化,那么它只能被实例化一次. 单体模式,就是将代码组织为一个逻辑单元,这个逻辑单元中的代码可以通过单一的变量进行访问 ...

  10. LNMP安装WordPress3.4.2看不到主题解决方法

    喜欢LNMP配置环境的朋友,又是wordpress建立的博客程序,安装之后发现一个问题在网站后台看不到模板主题,重新下载了一款新的主题也查看不了.开始以为是程序的问题,于是我重新下载新版本的WordP ...