题意:

树上找两个点  使得其它点到这两点随意一点的距离的最大值最小

思路:

最大值最小  想到二分  在二分的基础上判定这个最大值是否可能

怎样判定这个问题就是怎样选那两个点的问题  非常明显  我们要处理的是直径(不然没意义  最长的就是直径)  那么既然已经有了一个要判定的值x  最好还是就选择距离直径两端点距离为x的点就好

直径上的点最多n个  算上二分的复杂度  O(nlogn)能够解决

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<cstdlib>
#include<ctime>
#include<cmath>
using namespace std;
typedef long long LL;
#define N 200010int t, n;
struct edge {int v, next;
} ed[N * 2];
int head[N], tot;
int dis[N], pre[N];
int route[N], m;void add(int u, int v) {ed[tot].v = v;ed[tot].next = head[u];head[u] = tot++;
}int qu[N];
int bfs(int u) {int l = 0, r = 1;int pos = u, val = 0;dis[u] = 0;qu[0] = u;while (l < r) {u = qu[l++];for (int i = head[u]; ~i; i = ed[i].next) {int v = ed[i].v;if (dis[v] == -1) {pre[v] = u;dis[v] = dis[u] + 1;qu[r++] = v;if (dis[v] > val) {val = dis[v];pos = v;}}}}return pos;
}int flag[N];
bool yes(int ans) {memset(flag, 0, sizeof(flag));memset(dis, -1, sizeof(dis));bfs(route[ans]);for (int i = 1; i <= n; i++) {if (dis[i] <= ans)flag[i] = 1;}memset(dis, -1, sizeof(dis));bfs(route[m - 1 - ans]);for (int i = 1; i <= n; i++) {if (dis[i] <= ans)flag[i] = 1;}for (int i = 1; i <= n; i++) {if (!flag[i])return false;}return true;
}int main() {int i, u, v;scanf("%d", &t);while (t--) {tot = 0;memset(head, -1, sizeof(head));scanf("%d", &n);for (i = 1; i < n; i++) {scanf("%d%d", &u, &v);add(u, v);add(v, u);}memset(dis, -1, sizeof(dis));u = bfs(1);memset(dis, -1, sizeof(dis));memset(pre, -1, sizeof(pre));v = bfs(u);m = 0;while (v != -1) {route[m++] = v;v = pre[v];}int l = 0, r = m - 1, mid, ans[3];while (l <= r) {mid = (l + r) / 2;if (yes(mid)) {ans[0] = mid;ans[1] = route[mid];ans[2] = route[m - 1 - mid];if (ans[1] == ans[2]) {for (i = 0; i < m; i++) {if (route[i] != ans[1]) {ans[2] = route[i];break;}}}r = mid - 1;} elsel = mid + 1;}printf("%d %d %d\n", ans[0], ans[1], ans[2]);}return 0;
}

ZOJ 3820 Building Fire Stations相关推荐

  1. Building Fire Stations 39届亚洲赛牡丹江站B题

    题意:      给你一棵树,让你再里面选取两个点作为**点,然后所有点的权值是到这两个点中最近的那个的距离,最后问距离中最长的最短是多少,输出距离还有那两个点(spj特判). 思路:      现场 ...

  2. Building Fire Stations

    题目链接 首先找到树的直径,直径左端点是a,直径右端点是b,中间的点是mid(偶数的情况下mid可以看做两个),两点因该是左右分布: 假设两点都不在直径上,那么移到直径上的话距离更短: 设直径上左边的 ...

  3. 计算机辅助建筑设计英文全称是,计算机辅助建筑消防安全设计,computer-aided building fire safety design,音标,读音,翻译,英文例句,英语词典...

    补充资料:计算机辅助建筑设计 计算机辅助建筑设计 computer aided architectural design, CAAD ]isuanli fuzhu]ianzhu sheji计算机辅助建 ...

  4. 2000门课程名称翻译大全,写英文简历时用得着的

    C 语言 C Language  CAD 概论 Introduction to CAD  CAD/CAM CAD/CAM  COBOL语言 COBOL Language  生物物理学 Biophysi ...

  5. 2000 门课程名称英文翻译大全

    C 语言 C Language CAD 概论 Introduction to CAD CAD/CAM CAD/CAM COBOL语言 COBOL Language 生物物理学 Biophysics 真 ...

  6. 成绩单课程翻译参考总表

    生物物理学 Biophysics 真空冷冻干燥技术 Vacuum Freezing & Drying Technology 16位微机 16 Digit Microcomputer ALGOL ...

  7. 2000门课程名称翻译大全

    2000门课程名称翻译大全 BASIC 语言及应用 BASIC Language & Application C 语言 C Language CAD 概论 Introduction to CA ...

  8. 2062门课程名称翻译大全

    发信人: Waltwinner (麦田守望者), 信区: SchoGrad 标  题: 2062门课程名称翻译大全 发信站: BBS 碧海青天站 (Sun Aug 27 15:28:28 2006), ...

  9. 1000门课程中英互译

    16位微机 16 Digit Microcomputer  ALGOL语言 ALGOL Language  BASIC 语言 BASIC Language  BASIC 语言及应用 BASIC Lan ...

最新文章

  1. python实现真正的冒泡排序算法(时间复杂度优化版)!
  2. ipad写python_ipad怎么写python
  3. 四、用户、群组和权限(未完结)
  4. [转]JS导出PDF
  5. 【ThinkingInC++】66、pointer Stash的使用
  6. mysql前两个月_MySQL数据库表始终保持最近两个月的记录
  7. 区块链软件开发:DApps的五个制胜要点
  8. 2021中国统计摘要
  9. emoji语言抽象话大全_当抽象话也成为一种暗语
  10. 基于ARM9的无线电台网络控制系统的设计与研究
  11. IOT语义互操作性之本体论
  12. 记一次因为丢帧导致视频播放花屏问题的排查
  13. 面向 Java 开发人员的区块链链代码
  14. 如何判断车距:车距判断技巧图解
  15. android获取热点主机ip和连接热点手机ip
  16. 免费图片外链网站收集整理,不再为贴图而发愁!!
  17. C#合并多个richtextbox内容时始终存在换行符的解决方法
  18. ccs读取dat文件c语言程序,CCS中dat文件的格式
  19. 三羊献瑞-第六届蓝桥杯省赛
  20. DVB-S2工作总结

热门文章

  1. python comprehensions_python 列表生成式 List Comprehensions
  2. 红帽启动apache服务器_CentOS6.5环境下搭建Apache httpd服务器
  3. c语言如何跟进自定义赋值,用最简单的C语言编写自定义函数之数字后移
  4. DataBinding
  5. 小码哥iOS学习笔记第二天: OC对象的分类
  6. zabbix3 通过snmpv3监控linux主机
  7. Cassandra 原理介绍
  8. ORACLE 修改SID
  9. 在ubuntu 下 利用svn命令导出 两个版本之间更改的文件
  10. c++ 判断nil_golang A=nil,B=A,but B!=nil 这是真的