ZOJ 3820 Building Fire Stations
题意:
树上找两个点 使得其它点到这两点随意一点的距离的最大值最小
思路:
最大值最小 想到二分 在二分的基础上判定这个最大值是否可能
怎样判定这个问题就是怎样选那两个点的问题 非常明显 我们要处理的是直径(不然没意义 最长的就是直径) 那么既然已经有了一个要判定的值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相关推荐
- Building Fire Stations 39届亚洲赛牡丹江站B题
题意: 给你一棵树,让你再里面选取两个点作为**点,然后所有点的权值是到这两个点中最近的那个的距离,最后问距离中最长的最短是多少,输出距离还有那两个点(spj特判). 思路: 现场 ...
- Building Fire Stations
题目链接 首先找到树的直径,直径左端点是a,直径右端点是b,中间的点是mid(偶数的情况下mid可以看做两个),两点因该是左右分布: 假设两点都不在直径上,那么移到直径上的话距离更短: 设直径上左边的 ...
- 计算机辅助建筑设计英文全称是,计算机辅助建筑消防安全设计,computer-aided building fire safety design,音标,读音,翻译,英文例句,英语词典...
补充资料:计算机辅助建筑设计 计算机辅助建筑设计 computer aided architectural design, CAAD ]isuanli fuzhu]ianzhu sheji计算机辅助建 ...
- 2000门课程名称翻译大全,写英文简历时用得着的
C 语言 C Language CAD 概论 Introduction to CAD CAD/CAM CAD/CAM COBOL语言 COBOL Language 生物物理学 Biophysi ...
- 2000 门课程名称英文翻译大全
C 语言 C Language CAD 概论 Introduction to CAD CAD/CAM CAD/CAM COBOL语言 COBOL Language 生物物理学 Biophysics 真 ...
- 成绩单课程翻译参考总表
生物物理学 Biophysics 真空冷冻干燥技术 Vacuum Freezing & Drying Technology 16位微机 16 Digit Microcomputer ALGOL ...
- 2000门课程名称翻译大全
2000门课程名称翻译大全 BASIC 语言及应用 BASIC Language & Application C 语言 C Language CAD 概论 Introduction to CA ...
- 2062门课程名称翻译大全
发信人: Waltwinner (麦田守望者), 信区: SchoGrad 标 题: 2062门课程名称翻译大全 发信站: BBS 碧海青天站 (Sun Aug 27 15:28:28 2006), ...
- 1000门课程中英互译
16位微机 16 Digit Microcomputer ALGOL语言 ALGOL Language BASIC 语言 BASIC Language BASIC 语言及应用 BASIC Lan ...
最新文章
- python实现真正的冒泡排序算法(时间复杂度优化版)!
- ipad写python_ipad怎么写python
- 四、用户、群组和权限(未完结)
- [转]JS导出PDF
- 【ThinkingInC++】66、pointer Stash的使用
- mysql前两个月_MySQL数据库表始终保持最近两个月的记录
- 区块链软件开发:DApps的五个制胜要点
- 2021中国统计摘要
- emoji语言抽象话大全_当抽象话也成为一种暗语
- 基于ARM9的无线电台网络控制系统的设计与研究
- IOT语义互操作性之本体论
- 记一次因为丢帧导致视频播放花屏问题的排查
- 面向 Java 开发人员的区块链链代码
- 如何判断车距:车距判断技巧图解
- android获取热点主机ip和连接热点手机ip
- 免费图片外链网站收集整理,不再为贴图而发愁!!
- C#合并多个richtextbox内容时始终存在换行符的解决方法
- ccs读取dat文件c语言程序,CCS中dat文件的格式
- 三羊献瑞-第六届蓝桥杯省赛
- DVB-S2工作总结
热门文章
- python comprehensions_python 列表生成式 List Comprehensions
- 红帽启动apache服务器_CentOS6.5环境下搭建Apache httpd服务器
- c语言如何跟进自定义赋值,用最简单的C语言编写自定义函数之数字后移
- DataBinding
- 小码哥iOS学习笔记第二天: OC对象的分类
- zabbix3 通过snmpv3监控linux主机
- Cassandra 原理介绍
- ORACLE 修改SID
- 在ubuntu 下 利用svn命令导出 两个版本之间更改的文件
- c++ 判断nil_golang A=nil,B=A,but B!=nil 这是真的