HDU 4612 Warm up (边双连通分量+缩点+树的直径)
<题目链接>
题目大意:
给出一个连通图,问你在这个连通图上加一条边,使该连通图的桥的数量最小,输出最少的桥的数量。
解题分析:
首先,通过Tarjan缩点,将该图缩成一颗树,树上的每个节点都是一个边双连通分量,树上的每条边都是桥,现在需要挑出两个点,将它们直接相连,这样它们原始路径上所有的桥因为形成了环而全部消失,因此为了使剩下的桥最少,我们需要找到路径上桥最多的两点,又由于缩点后,树的每条边都是桥,所以这里就转化为树上距离两点的最远距离,也就是求树的直径。
下面Tarjan的时候需要注意的是,vis记录的是访问过边的编号不是节点的编号。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; #define mem(a,b) memset(a,b,sizeof(a)) typedef pair<int, int> pll; ; ; int num, num1, top, cnum,maxdis, pos,cnt; int head[N], head1[N], dis[N],instk[N], stk[N], dfn[N], low[N], belong[N]; ]; struct Edge{ int to, next; }e[M<<], e1[M<<]; void add(int u, int v) { e[num].to = v, e[num].next = head[u], head[u] = num++; } void add1(int u, int v) { e1[num1].to = v, e1[num1].next = head1[u], head1[u] = num1++; } void init() { num = num1 = cnt = cnum = top = ; mem(head,-),mem(head1,-),mem(belong,),mem(instk,); mem(vis,),mem(stk,),mem(dfn,),mem(low,),mem(dis,); } pll edge[M]; void tarjan(int u){ dfn[u] = low[u] = ++cnt; instk[u] = ; stk[++top] = u; for(int i = head[u]; ~i; i = e[i].next) { int v = e[i].to; if(vis[i])continue; vis[i] = vis[i^] = ; //将正、反两边全部标记 if(!dfn[v]) { tarjan(v); low[u] = min(low[u], low[v]); } else if(instk[v]) { low[u] = min(low[u], dfn[v]); } } if(low[u] == dfn[u]) { ++cnum; //cnum为边双连通分量的数量 int v; do{ v = stk[top--]; instk[v] = ; belong[v] = cnum; //将该连通块染色 } while(v != u); } } void bfs(int u){ queue <int> q; q.push(u); dis[u] = ; mem(vis,); vis[u] = ; maxdis = , pos = u; while(!q.empty()) { int u = q.front(); q.pop(); for(int i = head1[u]; ~i; i = e1[i].next) { int v = e1[i].to; if(vis[v])continue; vis[v] = ; dis[v] = dis[u]+; if(dis[v]>maxdis) { //更新树上的最远距离 maxdis = dis[v]; pos = v; //并且记录下该点 } q.push(v); } } } int main() { int n, m, x, y; while(scanf("%d%d",&n,&m)!=EOF,n||m){ init(); ; i<m; i++) { scanf("%d%d", &x, &y); edge[i].first = x, edge[i].second = y; //记录下所有的边,用结构体记录也可以 add(x, y),add(y, x); } tarjan(); ; ; i<m; i++){ //将缩点后的所有点建图,跑BFS,求树的直径 int x = edge[i].first, y = edge[i].second; if(belong[x]!=belong[y]) { add1(belong[x], belong[y]); add1(belong[y], belong[x]); edgenum++; //桥的数量+1 } } bfs(belong[]); bfs(pos); //求出此时树的直径,即一条路径上所含的最多桥的数量 int ans = edgenum-maxdis; printf("%d\n", ans); } }
2018-11-07
HDU 4612 Warm up (边双连通分量+缩点+树的直径)的更多相关文章
- HDU 4612 Warm up(双连通分量缩点+求树的直径)
思路:强连通分量缩点,建立一颗新的树,然后求树的最长直径,然后加上一条边能够去掉的桥数,就是直径的长度. 树的直径长度的求法:两次bfs可以求,第一次随便找一个点u,然后进行bfs搜到的最后一个点v, ...
- hdu4612 Warm up[边双连通分量缩点+树的直径]
给你一个连通图,你可以任意加一条边,最小化桥的数目. 添加一条边,发现在边双内是不会减少桥的.只有在边双与边双之间加边才有效.于是,跑一遍边双并缩点,然后就变成一棵树,这样要加一条非树边,路径上的点( ...
- HDU 4612 Warm up (边双连通分量+DP最长链)
[题意]给定一个无向图,问在允许加一条边的情况下,最少的桥的个数 [思路]对图做一遍Tarjan找出桥,把双连通分量缩成一个点,这样原图就成了一棵树,树的每条边都是桥.然后在树中求最长链,这样在两端点 ...
- Gym - 100676H H. Capital City (边双连通分量缩点+树的直径)
https://vjudge.net/problem/Gym-100676H 题意: 给出一个n个城市,城市之间有距离为w的边,现在要选一个中心城市,使得该城市到其余城市的最大距离最短.如果有一些城市 ...
- 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 边双连通分量+缩点+最长链
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612 简单图论题,先求图的边双连通分量,注意,此题有重边(admin还逗比的说没有重边),在用targ ...
- hdu4612(双连通缩点+树的直径)
传送门:Warm up 题意:询问如何加一条边,使得剩下的桥的数目最少,输出数目. 分析:tarjan缩点后,重新建图得到一棵树,树上所有边都为桥,那么找出树的直径两个端点连上,必定减少的桥数量最多, ...
- 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 ...
随机推荐
- VM_Centos7.3_X64_安装Oracle12C 总结笔记
声明:本文居多内容参考原文来之网络: 一:安装Centos7.3 虚拟机 1:操作系统下载 CentOS 7官方下载地址:https://www.centos.org/download/ 说明:本案例 ...
- Confluence 6 配置 简易信息聚合(RSS)
一个 Confluence 的管理员可以配置下面的 RSS 特性: Confluence 针对 RSS 聚合返回的最大项目数量. Confluence 针对 RSS 聚合允许的最大时间周期. 上面两个 ...
- Confluence 6 数据库表-授权(Authentication)
下面的表格对用户授权有关的信息进行存储,这部分是通过嵌入到 Confluence 中的 Atlassian Crowd 框架实现的. cwd_user Confluence 中每一个用户的信息. c ...
- 整合 JIRA 和 Confluence 6
Jira 应用和 Confluence 可以完全的整合在一起.在 Confluence 中收集你项目组成员的想法,知识和计划.在 Jira 中跟踪你的系统出现的问题,让这 2 个应用同时工作. 了解更 ...
- 修改Mysql5.7的root密码
Mysql5.7修改root密码 禁用root密码 1.修改 /etc/my.cnf,在 [mysqld] 小节下添加一行:skip-grant-tables=1 这一行配置让 mysqld 启动时不 ...
- TabLayout和ViewPager
这里就说下tablayout+viewpager的实现方式:tablayout是android5.0推出来的一个MaterialDesign风格的控件,是专门用来实现tab栏效果的:功能强大,使用方便 ...
- Android 基础 二 四大组件 Activity
Activity Intent IntentFilter 一理论概述 一. Activity 用来提供一个能让用户操作并与之交互的界面. 1.1 启动 startActivity(Intent int ...
- SpringMVC环境搭建
Spring MVC为展现层提供的基于MVC设计理念的优秀Web框架,是目前最主流的MVC框架之一. Spring 3.0之后完全超越Struts2,称为最优秀的MVC框架.学完SpringMVC之后 ...
- PHP实现动态获取函数参数的方法
1. func_num_args — 返回传入函数的参数总个数 int func_num_args ( void ) 示例 <?php function demo () { $numargs = ...
- 20165314 2016-2017-2 《Java程序设计》第7周学习总结
20165314 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 MySQL数据库管理系统 连接MySQL数据库 JDBC 批处理 代码托管