博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NCPC 2015 - Problem A - Adjoin the Networks
阅读量:4604 次
发布时间:2019-06-09

本文共 2744 字,大约阅读时间需要 9 分钟。

 

 

题目链接 : http://codeforces.com/gym/100781/attachments

 

 

题意 : 

有n个编号为0-n-1的点, 给出目前已经有的边(最多n-1条), 问如何添加最少的边, 使得整个图连通, 且其中两点间距离的最大值最小, 一条边距离为1单位

 

思路 : 

两点间距离的情况 : 1. 子图中任意两点间距离   2.两个子图中两点间的距离

无论如何添加边对第一种的距离都没有影响, 对第二种却有影响

考虑添加一条边连通两个子图后, 最长的距离为 子图1中距离添加边的节点的最长的距离 + 子图2中距离添加边的节点的最长的距离 + 添加的1条边的距离

所以选择添加边的节点是 在某个子图中, 使所有节点到它的最长距离最小的点

但是不用算出这个点, 只需要这个距离, 这个距离就是一个子图中距离最长两点距离的一半, 即(max_length + 1) / 2

一个图中最长距离求法是在对某个子图任一节点深搜, 搜到距离最长的点, 再对这个点深搜, 记录最长距离(新技能)

 

最终取 : 情况1 和 情况2 距离最大值

注意情况二中, 如果存在三个子图最大(max_length + 1) / 2 都相等, 最终答案是要加2条边的距离而不是加1条, 比如0-1    1-2    3-4 这三个子图

 

1 #include 
2 #include
3 #include
4 #include
5 6 using namespace std; 7 8 const int MAXN = 1e5+10; 9 10 vector
edge[MAXN];11 int depth[MAXN];12 bool vis[MAXN];13 int maxx, maxx1, mark1;14 int length[MAXN];15 16 int Max(int a, int b)17 {18 return a > b ? a : b;19 }20 21 void Dfs(int u, int fa)22 {23 vis[u] = 1;24 depth[u] = depth[fa] + 1;25 if(depth[u] > maxx1) {26 mark1 = u;27 maxx1 = depth[u];28 }29 int len = edge[u].size();30 for(int i = 0; i < len; i++) {31 int v = edge[u][i];32 if(v == fa) continue;33 Dfs(v, u);34 }35 }36 37 bool cmp(int a, int b)38 {39 return a > b;40 }41 42 void Init(int n)43 {44 for(int i = 0; i <= n; i++) {45 edge[i].clear();46 vis[i] = 0;47 }48 maxx = 0;49 }50 51 int main()52 {53 int n, l;54 int u, v;55 56 while(scanf("%d %d", &n, &l) != EOF) {57 Init(n);58 for(int i = 0; i < l; i++) {59 scanf("%d %d", &u, &v);60 edge[u].push_back(v);61 edge[v].push_back(u);62 }63 int cnt = 0;64 for(int i = 0; i < n; i++) {65 maxx1 = 0;66 if(vis[i] == 0) {67 depth[i] = -1;68 Dfs(i, i);69 depth[mark1] = -1;70 if(maxx1 != 0) {71 Dfs(mark1, mark1);72 }73 length[i] = (maxx1 + 1) / 2;74 if(maxx1 > maxx) maxx = maxx1;75 cnt++;76 }77 }78 sort(length, length+n, cmp);79 if(n == 1) printf("0\n");80 else if(n == 2) printf("1\n");81 else if(n == 3) printf("2\n");82 else if(cnt == 1) printf("%d\n", maxx);83 else if(length[0] == length[1] && length[1] == length[2]) {84 printf("%d\n", Max(maxx, length[0] + length[1] + 2));85 }86 else {87 printf("%d\n", Max(maxx, length[0] + length[1] + 1));88 }89 }90 91 return 0;92 }

 

转载于:https://www.cnblogs.com/Quinte/p/4891223.html

你可能感兴趣的文章
C语言 喝汽水问题
查看>>
LINUX中搭建DNS服务器,实现正向、反向以及访问不同DNS解析
查看>>
SCCM2012 R2实战系列之十:解决WDS服务无法启动问题(错误1067:进程意外终止)...
查看>>
ubuntu 下安装 mysql
查看>>
关于k-means聚类算法的matlab实现
查看>>
Git分支2
查看>>
一键安装Gitlab后的备份、迁移与恢复
查看>>
因为本人工作繁忙,精力有限,本博客停止更新。有兴趣的博友可以关注我在CSDN上的主博客...
查看>>
SQL server查看触发器是否被禁用
查看>>
[C++基础]在构造函数内部调用构造函数
查看>>
跟随我在oracle学习php(8)
查看>>
Spring 3.1.0 Hibernate 3.0 Eclipse Spring WEB例子
查看>>
UVA-10212 The Last Non-zero Digit. 分解质因子+容斥定理
查看>>
求两个集合的交集,并集,差集
查看>>
Kotlin的语法糖(一)基础篇
查看>>
OkHttp源码分析
查看>>
让你的app体验更丝滑的11种方法!冲击手机应用榜单Top3指日可待
查看>>
windows kernel exploitation基础教程
查看>>
NS_OPTIONS枚举的用法
查看>>
java9系列(九)Make G1 the Default Garbage Collector
查看>>