hdu4612 Warm up[边双连通分量缩点+树的直径]
给你一个连通图,你可以任意加一条边,最小化桥的数目。
添加一条边,发现在边双内是不会减少桥的。只有在边双与边双之间加边才有效。于是,跑一遍边双并缩点,然后就变成一棵树,这样要加一条非树边,路径上的点(边双)就都变成一个大边双了,所以问题转化为求树上最长路径,跑直径即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define mst(x) memset(x,0,sizeof x)
#define dbg(x) cerr << #x << " = " << x <<endl
#define dbg2(x,y) cerr<< #x <<" = "<< x <<" "<< #y <<" = "<< y <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=2e5+,M=1e6+;
struct thxorz{int to,nxt;}G1[M<<],G2[N<<];
int Head1[N],Head2[N],tot1,tot2;
int n,m;
inline void Addedge(int x,int y){
G1[++tot1].to=y,G1[tot1].nxt=Head1[x],Head1[x]=tot1;
G1[++tot1].to=x,G1[tot1].nxt=Head1[y],Head1[y]=tot1;
}
inline void Addtedge(int x,int y){
G2[++tot2].to=y,G2[tot2].nxt=Head2[x],Head2[x]=tot2;
G2[++tot2].to=x,G2[tot2].nxt=Head2[y],Head2[y]=tot2;
}
#define y G1[j].to
int dfn[N],low[N],cut[M<<],cnt;
void tarjan(int x,int i){
dfn[x]=low[x]=++cnt;
for(register int j=Head1[x];j;j=G1[j].nxt)if(j^(i^)){
if(!dfn[y]){
tarjan(y,j);MIN(low[x],low[y]);
if(low[y]>dfn[x])cut[j]=cut[j^]=;
}
else MIN(low[x],dfn[y]);
}
}
int bel[N],dcc;
void dfs(int x){
bel[x]=dcc;
for(register int j=Head1[x];j;j=G1[j].nxt)if(!bel[y]&&!cut[j])dfs(y);
}
#undef y
#define y G2[j].to
int dep,pt;
void tree_dfs(int x,int fa,int d){
if(MAX(dep,d))pt=x;
for(register int j=Head2[x];j;j=G2[j].nxt)if(y^fa)tree_dfs(y,x,d+);
}
#undef y
int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
while(read(n),read(m),n||m){
tot1=;dcc=tot2=cnt=dcc=;mst(Head1),mst(Head2),mst(dfn),mst(low),mst(cut),mst(bel);
for(register int i=,x,y;i<=m;++i)read(x),read(y),Addedge(x,y);
for(register int i=;i<=n;++i)if(!dfn[i])tarjan(i,);
for(register int i=;i<=n;++i)if(!bel[i])++dcc,dfs(i);
for(register int t=,u,v;t<=tot1;t+=){
u=G1[t].to,v=G1[t^].to;
if(bel[u]^bel[v])Addtedge(bel[u],bel[v]);//dbg2(bel[u],bel[v]);
}
dep=,tree_dfs(,,);dep=,tree_dfs(pt,,);
printf("%d\n",dcc-dep);
}
return ;
}
总结:和桥有关的可以首先考虑缩点建树,因为树有很好的性质,并且树边都是有桥连接起来的,同一个边双方便处理。
hdu4612 Warm up[边双连通分量缩点+树的直径]的更多相关文章
- HDU 4612 Warm up (边双连通分量+缩点+树的直径)
<题目链接> 题目大意:给出一个连通图,问你在这个连通图上加一条边,使该连通图的桥的数量最小,输出最少的桥的数量. 解题分析: 首先,通过Tarjan缩点,将该图缩成一颗树,树上的每个节点 ...
- HDU-4612 Warm up 边双连通分量+缩点+最长链
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612 简单图论题,先求图的边双连通分量,注意,此题有重边(admin还逗比的说没有重边),在用targ ...
- Gym - 100676H H. Capital City (边双连通分量缩点+树的直径)
https://vjudge.net/problem/Gym-100676H 题意: 给出一个n个城市,城市之间有距离为w的边,现在要选一个中心城市,使得该城市到其余城市的最大距离最短.如果有一些城市 ...
- HDU4612 Warm up 边双连通分量&&桥&&树直径
题目的意思很简单,给你一个已经连通的无向图,我们知道,图上不同的边连通分量之间有一定数量的桥,题目要求的就是要你再在这个图上加一条边,使得图的桥数目减到最少. 首先要做的就是找出桥,以及每个点所各自代 ...
- HDU 4612 Warm up(双连通分量缩点+求树的直径)
思路:强连通分量缩点,建立一颗新的树,然后求树的最长直径,然后加上一条边能够去掉的桥数,就是直径的长度. 树的直径长度的求法:两次bfs可以求,第一次随便找一个点u,然后进行bfs搜到的最后一个点v, ...
- hdu 4612 Warm up 双连通缩点+树的直径
首先双连通缩点建立新图(顺带求原图的总的桥数,事实上因为原图是一个强连通图,所以桥就等于缩点后的边) 此时得到的图类似树结构,对于新图求一次直径,也就是最长链. 我们新建的边就一定是连接这条最长链的首 ...
- hdu4612(双连通缩点+树的直径)
传送门:Warm up 题意:询问如何加一条边,使得剩下的桥的数目最少,输出数目. 分析:tarjan缩点后,重新建图得到一棵树,树上所有边都为桥,那么找出树的直径两个端点连上,必定减少的桥数量最多, ...
- F - Warm up HDU - 4612 tarjan缩点 + 树的直径 + 对tajan的再次理解
题目链接:https://vjudge.net/contest/67418#problem/F 题目大意:给你一个图,让你加一条边,使得原图中的桥尽可能的小.(谢谢梁学长的帮忙) 我对重边,tarja ...
- POJ3177 Redundant Paths(边双连通分量+缩点)
题目大概是给一个无向连通图,问最少加几条边,使图的任意两点都至少有两条边不重复路径. 如果一个图是边双连通图,即不存在割边,那么任何两个点都满足至少有两条边不重复路径,因为假设有重复边那这条边一定就是 ...
随机推荐
- 一文带你了解babel-preset-env
参考链接:https://www.jianshu.com/p/000c2670672b
- .Net WebApi接口之Swagger UI 隐藏指定接口类或方法
swagger的一个最大的优点是能实时同步api与文档,但有些时候我们不想全部公开接口,而要隐藏或屏蔽一些接口类或方法,swagger也是支持的,只需要设置一下DocumentFilter方法. 第一 ...
- golang写入csv
package main import ( "encoding/csv" "fmt" "os" ) func main() { file, ...
- Reactor系列(十一)take获取
#java#reactor#take#获取# 获取Flux订阅数量 视频讲解: https://www.bilibili.com/video/av80322616/ FluxMonoTestCase. ...
- POI锁定列并设置Cell文本格式
SXSSFWorkbook workbook = new SXSSFWorkbook(); Font font = workbook.createFont(); CellStyle style = w ...
- PTA(Basic Level)1020.月饼
月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼.现给定所有种类月饼的库存量.总售价.以及市场的最大需求量,请你计算可以获得的最大收益是多少. 注意:销售时允许取出一部分库存.样 ...
- 正式发布! .NET开发控件集ComponentOne 新版本加入Blazor UI
近期,由葡萄城推出的ComponentOne .NET开发控件集正式发布最新版本! ComponentOne 是一套专注于企业 .NET开发.支持 .NET Core 平台,并完美集成于 Visual ...
- Win7 Eclipse 搭建spark java1.8编译环境,JavaRDD的helloworld例子
[学习笔记] Win7 Eclipse 搭建spark java1.8编译环境,JavaRDD的helloworld例子: 在eclipse oxygen上创建一个普通的java项目,然后把spark ...
- 【jmeter测试范例】001——TCP测试
1.打开Jmeter(或者运行NewDriver.java启动Jmeter) 2.新建一个测试计划 ······ 3.新建线程组 4.设置线程组的参数 1.线程的数量 2.要在多久内完成,即每个请求发 ...
- python 安装virtualenv和wxPython
有人说 Virtualenv.Fabric 和 PIP 是 Pythoneer 的三大神器 上一节说过了怎么安装PIP,下面继续安装virtualenv 安装wxPython时比较简单 sudo pi ...