ZOJ 3820:Building Fire Stations(树的直径 Grade C)
题意:
n个点的树,边长全为1,求找出两个点,使得树上离这两个点距离最远的那个点,到这两个点(中某个点就行)的距离最小。
思路:
求树直径,找中点,删除中间那条边(如果直径上点数为奇数,则删任何一侧都可),分成两个子树,再求中心,即为答案。
代码:
//14:12
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; #define N 200100 struct Graph{
struct Edge{
int to;
int next;
}e[N*];
int head[N];
int p;
void clear() {
p = ;
memset(head, -, sizeof(head));
}
void addedge(int u, int v) {
e[p].to = v;
e[p].next = head[u];
head[u] = p++;
}
}g; int n;
int dis[N];
int que[N*];
bool vis[N];
int fa[N]; void generateDis(const Graph &g, int s) {
memset(dis, 0x3f, sizeof(dis));
memset(vis, , sizeof(vis));
memset(fa, -, sizeof(fa));
dis[s] = ;
int hd = ;
int tl = ;
que[tl++] = s;
vis[s] = ;
while (hd < tl) {
int now = que[hd++];
vis[now] = ;
for (int i = g.head[now]; i != -; i = g.e[i].next) {
int to = g.e[i].to;
if (dis[to] > dis[now]+) {
dis[to] = dis[now]+;
if (!vis[to]) {
vis[to] = ;
fa[to] = now;
que[tl++] = to;
}
}
}
}
} pair<int, int> getTreeMidPoint(const Graph &g, int s, int &OUT_dis) {
generateDis(g, s);
for (int i = ; i <= n; i++) {
if (dis[i] == 0x3f3f3f3f) dis[i] = -;
}
int u = max_element(&dis[], &dis[]+n) - dis; generateDis(g, u);
for (int i = ; i <= n; i++) {
if (dis[i] == 0x3f3f3f3f) dis[i] = -;
}
int v = max_element(&dis[], &dis[]+n) - dis; //printf("u = %d, v = %d, dis[v] = %d\n", u, v, dis[v]); int now = v;
while (dis[now] > (dis[v]+)/) {
now = fa[now];
} OUT_dis = dis[v]/ + dis[v]%;
return {fa[now], now};
} int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%d", &n); g.clear();
for (int i = ; i < n-; i++) {
int a, b;
scanf("%d%d", &a, &b);
g.addedge(a,b);
g.addedge(b,a);
} int tmpdis[];
pair<int ,int> point = getTreeMidPoint(g, , tmpdis[]); //printf("all tree get (%d %d, dis=%d)\n", point.first, point.second, tmpdis[0]); for (int i = g.head[point.first]; i != -; i=g.e[i].next) {
if (g.e[i].to == point.second) g.e[i].to = point.first;
} for (int i = g.head[point.second]; i != -; i=g.e[i].next) {
if (g.e[i].to == point.first) g.e[i].to = point.second;
} pair<int ,int> pa = getTreeMidPoint(g, point.first, tmpdis[]);
pair<int ,int> pb = getTreeMidPoint(g, point.second, tmpdis[]); printf("%d %d %d\n", max(tmpdis[], tmpdis[]), pa.second, pb.second);
}
return ;
}
ZOJ 3820:Building Fire Stations(树的直径 Grade C)的更多相关文章
- 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(二分法+bfs)
题目链接:zoj 3820 Building Fire Stations 题目大意:给定一棵树.选取两个建立加油站,问说全部点距离加油站距离的最大值的最小值是多少,而且随意输出一种建立加油站的方式. ...
- zoj 3820 Building Fire Stations (二分+树的直径)
Building Fire Stations Time Limit: 5 Seconds Memory Limit: 131072 KB Special Judge Marjar ...
- zoj 3820 Building Fire Stations(树上乱搞)
做同步赛的时候想偏了,状态总是时好时坏.这状态去区域赛果断得GG了. 题目大意:给一棵树.让求出树上两个点,使得别的点到两个点较近的点的距离最大值最小. 赛后用O(n)的算法搞了搞,事实上这道题不算难 ...
- ZOJ 3820 Building Fire Stations 求中点+树的直径+BFS
题意:给一棵树,要求找出两个点,使得所有点到这两个点中距离与自己较近的一个点的距离的最大值(所有点的结果取最大的值,即最远距离)最小. 意思应该都能明白. 解法:考虑将这棵树摆直如下: 那么我们可以把 ...
- ZOJ 3820 Building Fire Stations
题意: 树上找两个点 使得其它点到这两点随意一点的距离的最大值最小 思路: 最大值最小 想到二分 在二分的基础上判定这个最大值是否可能 怎样判定这个问题就是怎样选那两个点的问题 非常明显 我 ...
- ZOJ Problem Set - 3820 Building Fire Stations 【树的直径 + 操作 】
题目:problemId=5374" target="_blank">ZOJ Problem Set - 3820 Building Fire Stations 题 ...
- zoj3820 Building Fire Stations 树的中心
题意:n个点的树,给出n-1条边,每条边长都是1,两个点建立防火站,使得其他点到防火站的最远距离最短. 思路:比赛的时候和队友一开始想是把这两个点拎起来,使得层数最少,有点像是树的中心,于是就猜测是将 ...
- Building Fire Stations ZOJ - 3820 (二分,树的直径)
大意: 给定树, 求两个点, 使得所有其他的点到两点的最短距离的最大值尽量小. 二分答案转为判定选两个点, 向外遍历$x$的距离是否能遍历完整棵树. 取直径两段距离$x$的位置bfs即可. #incl ...
随机推荐
- 2037: [Sdoi2008]Sue的小球
2037: [Sdoi2008]Sue的小球 链接 题解 论文 代码 #include<cstdio> #include<algorithm> #include<cstr ...
- JS 金钱格式化
JavaScript Money Format(用prototype对Number进行扩展) Number.prototype.formatMoney = function (places, symb ...
- 利用split方法计算字符串中出现字母最多的次数
最近练习一些简单的算法题,知道自己很不聪明,但却没想到用了这么久,划算不划算是个需要考虑的问题, 其中有个算法是:统计一个字符串出现最多的字母,网上很多自己的见解,但是才疏学浅,有些地方看的有点困难, ...
- 获取<考试>博文密码!o(*≧▽≦)ツ
就是CJ高二组通用的密码 如果你想知道,请联系QQ,3057244225,或者直接面对面问博主(...) 是我们的内部材料,原创题目是不能外传的.请谅解. 当然如果是原题的话我们是不会上锁的啦
- appium-手势密码实现-automationName 是Appium的情况
1. 红色区域的范围为:[66,575][1014,1523], 由于这块是一个整块,所以无法使用每个点的数据:因此只能使用LockPatternView对象拿到左上角的坐标值 2. 原理, 将九宫 ...
- unity灯光Lightmapping、LightProbes
1.为什么要用Lightmapping? 简单来说就是实时灯光计算十分耗时,随着光源越多,计算耗时会倍增.使用Lightmap模拟灯光带来的效果,便不用去计算灯光,会带来性能上的大大提升. 当然一个复 ...
- java初学1
1.Java主要技术和分支以及应用领域 (1)Java SE Java Platform,Standard Edition,Java SE 以前称为J2SE.它允许开发和部署在桌面.服务器.嵌入式环境 ...
- 孤荷凌寒自学python第二十二天python类的继承
孤荷凌寒自学python第二十二天python类的继承 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) python中定义的类可以继承自其它类,所谓继承的概念,我的理解 是,就是一个类B继承自 ...
- ironic-conductor与ipa交互clean部分代码分析
clean的动作会在provide和delete阶段才会触发 从代码分析: 对节点执行的node provide/deleted/clean会先发送到ironicclient ironicclient ...
- React02
目录 React 进阶提升 条件渲染 受控组件* 状态提升* 组件数据流 TODO-LIST 设置服务器端口 列表渲染 条目PropTypes检查类型 export & import Refs ...