hdu 4612 Warm up 双连通缩点+树的直径
首先双连通缩点建立新图(顺带求原图的总的桥数,事实上因为原图是一个强连通图,所以桥就等于缩点后的边)
此时得到的图类似树结构,对于新图求一次直径,也就是最长链。
我们新建的边就一定是连接这条最长链的首尾,这样就将原图的桥降低了直径个。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define maxn 200005
#define maxm 2000005
struct node
{
int to,vis,next;
}e[maxm],e2[maxm];
int head[maxn],head2[maxn],en,en2;
int belong[maxn],vis[maxn],dfn[maxn],low[maxn],cnt,bridge,col,stack[maxn],top;
bool use[maxn];
void add(int a,int b)
{
e[en].to=b;
e[en].vis=0;
e[en].next=head[a];
head[a]=en++;
e[en].to=a;
e[en].vis=0;
e[en].next=head[b];
head[b]=en++;
}
void add2(int a,int b)
{
e2[en2].to=b;
e2[en2].next=head2[a];
head2[a]=en2++;
e2[en2].to=a;
e2[en2].next=head2[b];
head2[b]=en2++;
}
void init()
{
top=cnt=col=bridge=en2=en=0;
memset(vis,0,sizeof(vis));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(use,0,sizeof(use));
memset(head2,-1,sizeof(head2));
memset(head,-1,sizeof(head));
}
void Tarjan (int u)
{
int v;
vis[u] = 1;
dfn[u] = low[u] = ++cnt;
stack[top++] = u;
for (int i = head[u];i != -1;i = e[i].next)
{
v = e[i].to;
if (e[i].vis) continue;
e[i].vis = e[i^1].vis = 1;
if (vis[v] == 1)
low[u] = min(low[u],dfn[v]);
if (!vis[v])
{
Tarjan (v);
low[u] = min(low[u],low[v]);
if (low[v] > dfn[u])
bridge ++;
}
}
if (dfn[u] == low[u])
{
++col;
do{
v = stack[--top];
vis[v] = 0;
belong[v] = col;
}while (u != v);
}
}
int len,st;
void dfs(int now,int sum,int fa)
{
use[now]=1;
if(sum>len) {st=now;len=sum;}
for(int i=head2[now];~i;i=e2[i].next)
{
if(!use[e2[i].to]) dfs(e2[i].to,sum+1,now);
}
}
inline int ReadInt()
{
char ch = getchar();
int data = 0;
while (ch < '0' || ch > '9')
{
ch = getchar();
}
do
{
data = data*10 + ch-'0';
ch = getchar();
}while (ch >= '0' && ch <= '9');
return data;
}
int main()
{
int n,m,a,b;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(!n&&!m) break;
init();
for(int i=1;i<=m;i++)
{
a=ReadInt();
b=ReadInt();
add(a,b);
}
Tarjan(1);
for(int i=1;i<=n;i++)
for(int j=head[i];~j;j=e[j].next)
{
int to=e[j].to;
if(belong[to]!=belong[i]) {add2(belong[to],belong[i]);}
}
len=0;dfs(1,0,-1);
memset(use,0,sizeof(use));
len=0;dfs(st,0,-1);
printf("%d\n",bridge-len);
}
return 0;
}
hdu 4612 Warm up 双连通缩点+树的直径的更多相关文章
- hdu 4612 Warm up 有重边缩点+树的直径
题目链接 Warm up Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Tot ...
- hdu 4612 Warm up 双连通+树形dp思想
Warm up Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total S ...
- hdu4612(双连通缩点+树的直径)
传送门:Warm up 题意:询问如何加一条边,使得剩下的桥的数目最少,输出数目. 分析:tarjan缩点后,重新建图得到一棵树,树上所有边都为桥,那么找出树的直径两个端点连上,必定减少的桥数量最多, ...
- 边双连通缩点+树dp 2015 ACM Arabella Collegiate Programming Contest的Gym - 100676H
http://codeforces.com/gym/100676/attachments 题目大意: 有n个城市,有m条路,每条路都有边长,如果某几个城市的路能组成一个环,那么在环中的这些城市就有传送 ...
- HDU 4612 Warm up (边双连通分量+缩点+树的直径)
<题目链接> 题目大意:给出一个连通图,问你在这个连通图上加一条边,使该连通图的桥的数量最小,输出最少的桥的数量. 解题分析: 首先,通过Tarjan缩点,将该图缩成一颗树,树上的每个节点 ...
- hdu4612 Warm up[边双连通分量缩点+树的直径]
给你一个连通图,你可以任意加一条边,最小化桥的数目. 添加一条边,发现在边双内是不会减少桥的.只有在边双与边双之间加边才有效.于是,跑一遍边双并缩点,然后就变成一棵树,这样要加一条非树边,路径上的点( ...
- Gym - 100676H H. Capital City (边双连通分量缩点+树的直径)
https://vjudge.net/problem/Gym-100676H 题意: 给出一个n个城市,城市之间有距离为w的边,现在要选一个中心城市,使得该城市到其余城市的最大距离最短.如果有一些城市 ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
- Hdu 4612 Warm up (双连通分支+树的直径)
题目链接: Hdu 4612 Warm up 题目描述: 给一个无向连通图,问加上一条边后,桥的数目最少会有几个? 解题思路: 题目描述很清楚,题目也很裸,就是一眼看穿怎么做的,先求出来双连通分量,然 ...
随机推荐
- php配置redis支持
在php.ini里面添加下面两行,注意这两行的顺序一定不要颠倒(扩展库下载网址https://github.com/phpredis/phpredis/downloads),同时注意这2个文件的版本一 ...
- 基于ArcEngine的影像数据管理系统研制
基于ArcEngine的影像数据管理系统研制 如果批处理,速度很慢,效率低. 详情如下: 分成很多小块的影像数据,要达到连续显示的效果,并导入ArcSDE for SQL Server中以方便管理.在 ...
- 记录一下八款开源 Android 游戏引擎
记录一下八款开源 Android 游戏引擎 虽然android学了点点,然后现在又没学了(我为啥这么没有恒心呢大哭).以后有时间还是要继续学android的,一定要啊!虽然现在没学android游戏编 ...
- nova的 microversion 实现
之前想写nova的policy的实现, 但是发现网上,有人写的很不错了. 但是个人认为存在一些问题. ref: http://www.cnblogs.com/shaohef/p/4527436.htm ...
- 枚举与剪枝_观察算式(比标准答案还要牛B)
观察算式 观察以下的算式: △△△ * △△ = △△△△ 某3位数乘以2位数,结果为4位数 要求:在9个△所代表的数字中.1~9的数字恰好每一个出现1次. 暴力破解代码: package lianx ...
- Page_Prerender介绍
它是asp.net页面的OnPreRender事件的处理程序.此事件是定义在Control类中的,因为Page类(aspx页面的基类)继承的是System.Web.UI.WebControl类,而We ...
- oracle 11g常用命令
1.监听启动监听lsnrctl start停止监听 lsnrctl stop 查看监听状态 lsnrctl status 2.启动用oracle用户进入su - oracle运行sqlplus命令,进 ...
- CSS:margin负数的使用
给所有div加上边框=10px之后,再给所有div设置margin-left与margin-top;以及浮动(float:left) 因此时需要鼠标悬停效果:所以设置给div设置伪类:hover,然因 ...
- activity的打开关闭动画
Activity的打开关闭或者说相互跳转之间可以设置动画的.默认的打开关闭直接消失或出现,比较不优美,但是有的手机Rom对这个默认做了修改,比如红米HM1,默认的就是新页面自右向左滑动出现,自左向右滑 ...
- Filemanager 的使用
filemanager的使用包括: 1.创建文件夹 2.删除文件夹 3.写入文件 4.复制文件 5.移动文件 6.删除文件 一.创建文件夹 首先宏的定义一个字符串作为地址的来获取当前的docum ...