Building Fire Stations


Time Limit: 5 Seconds     
Memory Limit: 131072 KB      Special Judge


Marjar University is a beautiful and peaceful place. There are N buildings and
N - 1 bidirectional roads in the campus. These buildings are connected by roads in such a way that there is exactly one path between any two buildings. By coincidence, the length of each road is 1 unit.

To ensure the campus security, Edward, the headmaster of Marjar University, plans to setup two fire stations in two different buildings so that firefighters are able to arrive at the scene of the fire as soon as possible whenever fires occur. That means
the longest distance between a building and its nearest fire station should be as short as possible.

As a clever and diligent student in Marjar University, you are asked to write a program to complete the plan. Please find out two proper buildings to setup the fire stations.

Input

There are multiple test cases. The first line of input contains an integer
T
indicating the number of test cases. For each test case:

The first line contains an integer N (2 <= N <= 200000).

For the next N - 1 lines, each line contains two integers Xi and
Yi. That means there is a road connecting building Xi and building
Yi (indexes are 1-based).

Output

For each test case, output three integers. The first one is the minimal longest distance between a building and its nearest fire station. The next two integers are the indexes of the two buildings selected to build the fire stations.

If there are multiple solutions, any one will be acceptable.

Sample Input

2
4
1 2
1 3
1 4
5
1 2
2 3
3 4
4 5

Sample Output

1 1 2
1 2 4


题意:
给你一颗树。选两个点做消防站,使得全部点到近期消防站的最大距离最小。

思路:
能够yy到两个点选在树的直径上,于是能够二分答案,答案为 mid 的时候两个端点就应该选  st+mid   和  ed-mid 这两个点 (st、ed是树的直径的端点),然后枚举中间的那些点是否满足条件来检验就够了。


代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#define maxn 200005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std; int n,m,ans;
int st,ed,dd,resu,resv;
vector<int>edge[maxn];
int dist[maxn],pre[maxn],city[maxn];
int indst[maxn],inded[maxn];
bool vis[maxn],app[maxn]; int bfs(int sx)
{
int i,j,u,v,res;
queue<int>q;
memset(dist,-1,sizeof(dist));
memset(pre,0,sizeof(pre));
dist[sx]=dd=0;
q.push(sx);
while(!q.empty())
{
u=q.front();
if(dist[u]>=dd)
{
res=u; dd=dist[u];
}
q.pop();
for(i=0;i<edge[u].size();i++)
{
v=edge[u][i];
if(dist[v]==-1)
{
pre[v]=u;
dist[v]=dist[u]+1;
q.push(v);
}
}
}
return res;
}
int bfs1(int sx)
{
int i,j,u,v,res=0;
queue<int>q;
city[sx]=0;
q.push(sx);
while(!q.empty())
{
u=q.front();
res=max(res,city[u]);
q.pop();
for(i=0;i<edge[u].size();i++)
{
v=edge[u][i];
if(!vis[v]&&!app[v])
{
app[v]=1;
city[v]=city[u]+1;
q.push(v);
}
}
}
return res;
}
bool isok(int mid)
{
int i,j,u,v,tu=indst[mid],tv=inded[mid],gap=dist[ed]-2*mid;
//printf("mid:%d tu:%d tv:%d gap:%d\n",mid,tu,tv,gap);
u=tv;
int num=0;
while(u!=tu)
{
if(city[u]+min(num,gap-num)>mid) return false ;
u=pre[u];
num++;
}
return true ;
}
void solve()
{
int i,j,u,v,num=0;
st=bfs(1);
ed=bfs(st);
// printf("st:%d ed:%d\n",st,ed);
memset(vis,0,sizeof(vis));
u=ed;
while(u)
{
inded[num]=u; indst[dist[ed]-num]=u;
num++;
vis[u]=1;
u=pre[u];
}
memset(app,0,sizeof(app));
u=ed;
while(u)
{
city[u]=bfs1(u);
//printf("u:%d city:%d\n",u,city[u]);
u=pre[u];
}
int le=0,ri=dist[ed]/2,mid;
while(le<=ri)
{
mid=(le+ri)>>1;
if(isok(mid))
{
ans=mid; resu=indst[mid]; resv=inded[mid];
if(resu==resv) resu=pre[resu];
ri=mid-1;
}
else le=mid+1;
}
printf("%d %d %d\n",ans,resu,resv);
}
int main()
{
int i,j,t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++) edge[i].clear();
int u,v;
for(i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
edge[u].push_back(v);
edge[v].push_back(u);
}
solve();
}
return 0;
}

1 1 2
1 2 4

zoj 3820 Building Fire Stations (二分+树的直径)的更多相关文章

  1. ZOJ Problem Set - 3820 Building Fire Stations 【树的直径 + 操作 】

    题目:problemId=5374" target="_blank">ZOJ Problem Set - 3820 Building Fire Stations 题 ...

  2. zoj 3820 Building Fire Stations(二分法+bfs)

    题目链接:zoj 3820 Building Fire Stations 题目大意:给定一棵树.选取两个建立加油站,问说全部点距离加油站距离的最大值的最小值是多少,而且随意输出一种建立加油站的方式. ...

  3. zoj 3820 Building Fire Stations 树的中心

    Building Fire Stations Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge ...

  4. zoj 3820 Building Fire Stations(树上乱搞)

    做同步赛的时候想偏了,状态总是时好时坏.这状态去区域赛果断得GG了. 题目大意:给一棵树.让求出树上两个点,使得别的点到两个点较近的点的距离最大值最小. 赛后用O(n)的算法搞了搞,事实上这道题不算难 ...

  5. ZOJ 3820 Building Fire Stations 求中点+树的直径+BFS

    题意:给一棵树,要求找出两个点,使得所有点到这两个点中距离与自己较近的一个点的距离的最大值(所有点的结果取最大的值,即最远距离)最小. 意思应该都能明白. 解法:考虑将这棵树摆直如下: 那么我们可以把 ...

  6. ZOJ 3820:Building Fire Stations(树的直径 Grade C)

    题意: n个点的树,边长全为1,求找出两个点,使得树上离这两个点距离最远的那个点,到这两个点(中某个点就行)的距离最小. 思路: 求树直径,找中点,删除中间那条边(如果直径上点数为奇数,则删任何一侧都 ...

  7. ZOJ 3820 Building Fire Stations

    题意: 树上找两个点  使得其它点到这两点随意一点的距离的最大值最小 思路: 最大值最小  想到二分  在二分的基础上判定这个最大值是否可能 怎样判定这个问题就是怎样选那两个点的问题  非常明显  我 ...

  8. Building Fire Stations ZOJ - 3820 (二分,树的直径)

    大意: 给定树, 求两个点, 使得所有其他的点到两点的最短距离的最大值尽量小. 二分答案转为判定选两个点, 向外遍历$x$的距离是否能遍历完整棵树. 取直径两段距离$x$的位置bfs即可. #incl ...

  9. zoj3820 Building Fire Stations 树的中心

    题意:n个点的树,给出n-1条边,每条边长都是1,两个点建立防火站,使得其他点到防火站的最远距离最短. 思路:比赛的时候和队友一开始想是把这两个点拎起来,使得层数最少,有点像是树的中心,于是就猜测是将 ...

随机推荐

  1. Mysql学习总结(32)——MySQL分页技术详解

    1.什么是数据分页:数据分页就是将很多条记录像书本一样分页,每页显示多少行记录: 2.为什么要数据分页:当我们进行sql语句查询时,假如数据有成千上万行记录,如果在同一个页面去显示,那这个页面得有多大 ...

  2. mysql5.7官网直译SQL语句优化--分组优化

    1.14Group By Optimization 分组优化 大多数方法为了满足分组查询需要扫描整个表并且创建一个临时表,其中每组中的值都是连续的,如果可以使用聚合函数和临时表获取各个分组.在某些情况 ...

  3. CSS3可伸缩框属性,可用于等分显示子元素或按比例显示子元素的大小

    使用方法跟Android的android:layout_weight属性类似.可类比Android中的使用方法.这样比較好记,因为眼下全部浏览器都不支持大部分的属性,所以全部的属性都须要加上Firef ...

  4. Codeforces Round #274 (Div. 2) 解题报告

    题目地址:http://codeforces.com/contest/479 这次自己又仅仅能做出4道题来. A题:Expression 水题. 枚举六种情况求最大值就可以. 代码例如以下: #inc ...

  5. ES跨版本升级?——难道升级集群发生shard allocation是因为要分配replica节点???

    Full cluster restart upgrade Elasticsearch requires a full cluster restart when upgrading across maj ...

  6. POJ 1990 线段树

    题意: 思路: 线段树 (一棵就够啦 不像树状数组,还得用两棵) 先对v从小到大排序.每回插入的时候当前的v是最大的,只需要统计它到各个坐标的距离就好了. 里面存两个东西: 这个坐标左边的坐标个数和这 ...

  7. ios各个屏幕

    func currentDeviceScreenMeasurement() -> CGFloat { var deviceScree: CGFloat = 3.5 if ((568 == SCR ...

  8. 今天犯的一个错误,导致method GET must not have a request body

    事件经过: 1.在本地机器运行完全正常的程序,手动人工发包到测试环境上,后台日志频频报method GET must not have a request body. 2.使用postman发送pos ...

  9. python的import与from…import的区别

    [转]http://blog.csdn.net/windone0109/article/details/8996184 在python中用import或者from-import来导入相应的模块.模块其 ...

  10. UWP连接mysql 实现数据远程备份

    昨晚吃饭的时候突然觉得我们这个UWP应该添个数据备份的功能,不然换手机,换电脑之后数据库就全没了... 一开始是想用微软提供的AZURE的,没想到这玩意又没什么资料而且申请试用的时候还让我交身份证照片 ...