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 ...
随机推荐
- P1330 封锁阳光大学(染色问题)
P1330 封锁阳光大学 题目描述 曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街.河蟹看到欢快的曹,感到不爽.河蟹决定封锁阳光大学,不让曹刷街. 阳光大学的校园是一张由N个点构 ...
- 减少Android staido 占用C 盘
1.gradle 更换文件夹: 设置GRADLE_USER_HOME环境变量 在/etc/profile或~/.bash_profile增加如下: export GRADLE_USER_HOME=D: ...
- Android Stadio 相关
这几天,电脑坏了.重装系统,慢慢的学到了很多Android stadio 的相关知识.总结一下吧: 1.gradle 编译工具:在工程的gradle/wrapper/gradle–wrapper.pr ...
- Field 'flag' doesn't have a default value错误
错误代码: java.sql.SQLException: Field 'flag' doesn't have a default value at com.mysql.jdbc.SQLError.cr ...
- 平时收集的一些有关UED的团队和个人博客
平时收集的一些有关UED的团队和个人博客 前端团队阿里巴巴 UED -- 我们设计的界面,并没有几十亿的流量,但每天来自上百个国家的百万商人在使用着.阿里巴巴中国站UED -- 阿里巴巴中国站UED成 ...
- CodeIgniter学习笔记五:分页,文件上传,session,验证码
一.分页 示例代码: //装载类文件 $this -> load -> library('pagination'); $controller = $this->router-> ...
- linux统计分析流量-wireshark
wireshark是一款带界面的开源抓包工具,可以用来对系统流量进行统计分析. 安装 由于wireshark是带界面的,所以一般在界面环境下运行,可以通过yum安装: $ yum install -y ...
- 每天一个Linux命令(2):shutdown命令
shutdown命令是系统关机命令.shutdown指令可以关闭所有程序,并依用户的需要,进行重新开机或关机的动作. 语法 shutdown(选项)(参数) 选项 -c:取消已经在进行的 shutdo ...
- java初学2
1.数组操作类Arrays与System public static void arraycopy(Object src, int srcPos, Object dest,int destPos,in ...
- (笔记) RealTimeRender[实时渲染] C3
@author: 白袍小道 转载表明,查看随缘 前言: 从历史上看,图形加速始于每个像素扫描线上的插值颜色重叠一个三角形,然后显示这些值.包括访问图像数据允许纹理应用于表面.添加硬件 插入和测试z深度 ...