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. 【Codeforces Round #476 (Div. 2) [Thanks, Telegram!] A】Paper Airplanes

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 统计每个人需要的sheet个数. 乘上k 然后除p就是需要的pack个数了 [代码] #include <bits/stdc+ ...

  2. android studio2.2 配置NDK

    1.配置环境: Android studio2.2 配置NDK NDK版本[android-ndk-r13b-windows-x86_64.zip] NDK下载网址:[https://dl.googl ...

  3. Myeclipse学习总结(9)——MyEclipse2014安装插件的几种方式(适用于Eclipse或MyEclipse其他版本)

    众所周知MyEclipse是一个很强大的Java IDE,而且它有许多开源免费又好用的插件,这些插件给我们开发过程中带来了许多方便.插件具有针对性,例如,你如果做安卓开发,可能需要一个ADT(Andr ...

  4. java判断string数组中是否包含某个元素

  5. Qt之设置应用程序图标

    简述 应用程序图标,通常显示在应用程序的顶层窗口的左上角,通过调用QWindow:setWindowIcon()函数来实现. 为了改变可执行程序文件本身的图标,因为它被呈现在桌面上,它必须采用另一种依 ...

  6. C++的标准模板库STL中实现的数据结构之链表std::list的分析与使用

    摘要 本文主要借助对C++的标准模板库STL中实现的数据结构的学习和使用来加深对数据结构的理解,即联系数据结构的理论分析和详细的应用实现(STL),本文是系列总结的第二篇.主要针对线性表中的链表 ST ...

  7. hadoop系列:zookeeper(2)——zookeeper核心原理(选举)

    1.前述 上篇文章<hadoop系列:zookeeper(1)--zookeeper单点和集群安装>(http://blog.csdn.net/yinwenjie/article/deta ...

  8. ida动态调试so,在init_array和JNI_ONLOAD处下断点

    本文涉及到的apk.请在github下载https://github.com/jltxgcy/AliCrack/AliCrackme_2.apk. 0x00 怎样在JNI_ONLOAD下断点.參考安卓 ...

  9. 一个人的旅行 HDU杭电2066【dijkstra算法 || SPFA】

    pid=2066">http://acm.hdu.edu.cn/showproblem.php? pid=2066 Problem Description 尽管草儿是个路痴(就是在杭电 ...

  10. xxx while the managed IDbConnection interface was being used: Login failed for user xxx

    Process cube的时候遇到如下错误.   Errors in the high-level relational engine. The following exception occurre ...