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 200010 int 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;
} else
l = mid + 1;
}
printf("%d %d %d\n", ans[0], ans[1], ans[2]);
}
return 0;
}
ZOJ 3820 Building Fire Stations的更多相关文章
- zoj 3820 Building Fire Stations(二分法+bfs)
题目链接:zoj 3820 Building Fire Stations 题目大意:给定一棵树.选取两个建立加油站,问说全部点距离加油站距离的最大值的最小值是多少,而且随意输出一种建立加油站的方式. ...
- zoj 3820 Building Fire Stations 树的中心
Building Fire Stations Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge ...
- zoj 3820 Building Fire Stations (二分+树的直径)
Building Fire Stations Time Limit: 5 Seconds Memory Limit: 131072 KB Special Judge Marjar ...
- ZOJ 3820 Building Fire Stations 求中点+树的直径+BFS
题意:给一棵树,要求找出两个点,使得所有点到这两个点中距离与自己较近的一个点的距离的最大值(所有点的结果取最大的值,即最远距离)最小. 意思应该都能明白. 解法:考虑将这棵树摆直如下: 那么我们可以把 ...
- zoj 3820 Building Fire Stations(树上乱搞)
做同步赛的时候想偏了,状态总是时好时坏.这状态去区域赛果断得GG了. 题目大意:给一棵树.让求出树上两个点,使得别的点到两个点较近的点的距离最大值最小. 赛后用O(n)的算法搞了搞,事实上这道题不算难 ...
- ZOJ 3820:Building Fire Stations(树的直径 Grade C)
题意: n个点的树,边长全为1,求找出两个点,使得树上离这两个点距离最远的那个点,到这两个点(中某个点就行)的距离最小. 思路: 求树直径,找中点,删除中间那条边(如果直径上点数为奇数,则删任何一侧都 ...
- ZOJ Problem Set - 3820 Building Fire Stations 【树的直径 + 操作 】
题目:problemId=5374" target="_blank">ZOJ Problem Set - 3820 Building Fire Stations 题 ...
- Building Fire Stations ZOJ - 3820 (二分,树的直径)
大意: 给定树, 求两个点, 使得所有其他的点到两点的最短距离的最大值尽量小. 二分答案转为判定选两个点, 向外遍历$x$的距离是否能遍历完整棵树. 取直径两段距离$x$的位置bfs即可. #incl ...
- ZOJ-3820 Building Fire Stations 题解
题目大意: 一棵树,在其中找两个点,使得其他点到这两个的距离的较小值的最大值的最小值及其方案. 思路: 首先显然一棵树的直径的中点到其他点的距离的最大值必定比其他点的小. 那么感性思考一下就将一棵树的 ...
随机推荐
- 判断 iPhone 是否已插入 SIM 卡的方法
判断 iPhone 是否插入了 SIM 卡,可以参考苹果官网的 systemconfigure framework 教程,将下面的代码复制到头文件 extern NSString* const kCT ...
- Windows Phone开发(38):动画之PointAnimation
原文:Windows Phone开发(38):动画之PointAnimation PointAnimation也是很简单的,与前面说到的两个Animation是差不多的,属性也是一样的,如By.Fro ...
- Linux新手命令
给老婆写了一份速成培训教材--最经常使用的命令及解释.当然每一个人工作内容不同,经常使用命令也不同,这仅仅是我的个人经验,并且要考虑到接受者的基础. ls:列出文件夹下的内容,类似于dos下的dir. ...
- 使用2DToolkit报错“ OverflowException: Value is too large”
今天使用2DToolkit做图集和动画时报错“ OverflowException: Value is too large”,大侠们说是字符串转整型时超过了Int的大小范围,所以报错.后来我一位同事高 ...
- Google Maps Android API v2 (3)- 地图添加到Android应用程序
添加地图的基本步骤是: (一旦)按照以下步骤[入门] [开始],获得API,获取密钥所需的属性,并添加到您的Android清单. 添加一个碎片对象 要处理地图的活动.做到这一点最简单的方法是增加一个 ...
- WPF 引用DLL纯图像资源包类库中的图片
原文:WPF 引用DLL纯图像资源包类库中的图片 1.建立WPF应用程序 过程略. 2.创建类库项目(图片资源包) 创建图片资源类库项目MyImages,删除 ...
- redis入门(转)
Redis介绍 Redis是一种高级key-value数据库.它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富.有字符串,链表.哈希.集合和有序集合5种.支持在服务器端计算集合 ...
- 【原创】leetCodeOj ---Remove Duplicates from Sorted List II 解题报告
明日深圳行,心情紧张,写博文压压惊 囧 ------------------------------------- 原题地址: https://oj.leetcode.com/problems/rem ...
- BZOJ 1150 CTSC2007 数据备份Backup 堆+馋
标题效果:给定一个长度n−1n-1的序列,要求选出kk个不相邻的数使得和最小 费用流显然能跑.并且显然过不去- - 考虑用堆模拟费用流 一个错误的贪心是每次取最小.这样显然过不去例子 我们把[每次取最 ...
- SRM 628 D1L3:DoraemonPuzzleGame,math,后市展望,dp
称号:c=problem_statement&pm=13283&rd=16009">http://community.topcoder.com/stat?c=probl ...