hdu-4612-Warm up(边双连通分量--有重边)
题意:有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(边双连通分量--有重边)的更多相关文章
- HDU 4612 Warm up (边双连通分量+DP最长链)
[题意]给定一个无向图,问在允许加一条边的情况下,最少的桥的个数 [思路]对图做一遍Tarjan找出桥,把双连通分量缩成一个点,这样原图就成了一棵树,树的每条边都是桥.然后在树中求最长链,这样在两端点 ...
- HDU 4612 Warm up (边双连通分量+缩点+树的直径)
<题目链接> 题目大意:给出一个连通图,问你在这个连通图上加一条边,使该连通图的桥的数量最小,输出最少的桥的数量. 解题分析: 首先,通过Tarjan缩点,将该图缩成一颗树,树上的每个节点 ...
- HDU 4612 Warm up(双连通分量缩点+求树的直径)
思路:强连通分量缩点,建立一颗新的树,然后求树的最长直径,然后加上一条边能够去掉的桥数,就是直径的长度. 树的直径长度的求法:两次bfs可以求,第一次随便找一个点u,然后进行bfs搜到的最后一个点v, ...
- hdoj 4612 Warm up【双连通分量求桥&&缩点建新图求树的直径】
Warm up Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Su ...
- Hdu 4612 Warm up (双连通分支+树的直径)
题目链接: Hdu 4612 Warm up 题目描述: 给一个无向连通图,问加上一条边后,桥的数目最少会有几个? 解题思路: 题目描述很清楚,题目也很裸,就是一眼看穿怎么做的,先求出来双连通分量,然 ...
- HDU 4612——Warm up——————【边双连通分量、树的直径】
Warm up Time Limit:5000MS Memory Limit:65535KB 64bit IO Format:%I64d & %I64u Submit Stat ...
- 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 ...
- hdu 4612 Warm up 双连通+树形dp思想
Warm up Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total S ...
- [HDOJ4612]Warm up(双连通分量,缩点,树直径)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612 所有图论题都要往树上考虑 题意:给一张图,仅允许添加一条边,问能干掉的最多条桥有多少. 必须解决 ...
- HDU-4612 Warm up 边双连通分量+缩点+最长链
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612 简单图论题,先求图的边双连通分量,注意,此题有重边(admin还逗比的说没有重边),在用targ ...
随机推荐
- Java基础知识强化之集合框架笔记27:ArrayList集合练习之去除ArrayList集合中的重复字符串元素
1. 去除ArrayList集合中的重复字符串元素(字符串内容相同) 分析: (1)创建集合对象 (2)添加多个字符串元素(包含重复的) (3)创建新的集合 (4)遍历旧集合,获取得到每一个元素 (5 ...
- 使用附加导航(affix)实现内容切换
<!DOCTYPE html> <html> <head> <title> new document </title> <meta c ...
- Vim键盘图与命令图解
- oracle周数计算方法
从星期天开始起算 Function Fn_GetWeekbyDate(P_Date Varchar2) Return Varchar2 Is Begin Return To_char(To_Date( ...
- C#总结项目《影院售票系统》编写总结一
C#学习经历从基本语法结构到窗体再到面向对象终于走完了.NET初级程序员的道路,做为品德优良好学生更不能落下课程的总结项目-某某鸟<影院售票系统>.用了大概一天半的时间做完这个练手项目,先 ...
- 玩javaweb的web.xml编译路径
有时候能够碰到这样的情况 缓存就是 清不掉 那就可以去寻找编译路径了 <Context docBase="E:\java-workspace\eigyo_com405" pa ...
- angularjs-ngTable select filter
jsp <td title="'Status'" filter="{status: 'select'}" filter-data="fn.sta ...
- SQL Server 表字段值转换成字段名称(二)
上次写了个比较简单的只有两个字段的例子,经要求在写个 3 个字段的示例 ,贴上来与大家共勉一下 如果你们有更好的方法,提供一下, 感激不尽. 示例如下: /*--drop table temp_ ...
- C#winform程序自定义鼠标样式
public void SetCursor(Bitmap cursor, Point hotPoint) { int hotX = hotPoint.X; int hotY = hotPoint.Y; ...
- 【POJ3461】【KMP】Oulipo
Description The French author Georges Perec (1936–1982) once wrote a book, La disparition, without t ...