ZOJ 3820 Building Fire Stations 求中点+树的直径+BFS
题意:给一棵树,要求找出两个点,使得所有点到这两个点中距离与自己较近的一个点的距离的最大值(所有点的结果取最大的值,即最远距离)最小。 意思应该都能明白。
解法:考虑将这棵树摆直如下:

那么我们可以把最中间的那条直径边删掉,然后在分成的两颗子树内求一个直径中心点,那么这两个点就可以作为答案。 反正当时就觉得这样是正确的, 但是不能证明。
于是,几个bfs就可以搞定了。
当时写TLE了,原因是存要删的边我用了map<pair<int,int>,int>, 后来改掉就不T了,map这种东西还是尽量少用。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
using namespace std;
#define N 200007 int vis[N],fa[N];
int maxi,maxtag;
struct node
{
int dis,u;
};
vector<int> G[N];
int U,V; void bfs(int S)
{
node now;
now.u = S;
now.dis = ;
maxi = , maxtag = S;
queue<node> que;
fa[S] = -;
memset(vis,,sizeof(vis));
que.push(now);
vis[S] = ;
while(!que.empty())
{
node tmp = que.front();
que.pop();
int dis = tmp.dis;
int u = tmp.u;
if(dis > maxi) //最远的点
maxi = dis, maxtag = u;
for(int i=;i<G[u].size();i++)
{
int v = G[u][i];
if(vis[v]) continue;
if((u == U && v == V)||(u == V && v == U)) continue;
now.dis = dis+;
now.u = v;
fa[v] = u;
vis[v] = ;
que.push(now);
}
}
} int Smaxi,Smaxtag;
int Emaxi,Emaxtag; void findcenter(int S,int& ma,int& tag)
{
ma = , tag = S;
bfs(S);
int NS = maxtag;
bfs(NS);
int NE = maxtag;
int cnt = (maxi+)/;
int nc = ;
int i = NE;
while()
{
nc++;
if(nc > cnt)
{
tag = i;
break;
}
i = fa[i];
}
bfs(tag);
ma = maxi;
} int main()
{
int t,n,i,u,v;
scanf("%d",&t);
while(t--)
{
U = V = -;
scanf("%d",&n);
for(i=;i<=n;i++)
G[i].clear();
for(i=;i<n;i++)
{
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
bfs();
int S = maxtag;
bfs(S);
int E = maxtag;
int cnt = (maxi+)/;
int nc = ;
i = E;
while()
{
nc++;
if(nc >= cnt)
{
U = i, V = fa[i];
break;
}
i = fa[i];
}
findcenter(S,Smaxi,Smaxtag);
findcenter(E,Emaxi,Emaxtag);
printf("%d %d %d\n",max(Smaxi,Emaxi),Smaxtag,Emaxtag);
}
return ;
}
ZOJ 3820 Building Fire Stations 求中点+树的直径+BFS的更多相关文章
- 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 题目大意:给定一棵树.选取两个建立加油站,问说全部点距离加油站距离的最大值的最小值是多少,而且随意输出一种建立加油站的方式. ...
- 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(树上乱搞)
做同步赛的时候想偏了,状态总是时好时坏.这状态去区域赛果断得GG了. 题目大意:给一棵树.让求出树上两个点,使得别的点到两个点较近的点的距离最大值最小. 赛后用O(n)的算法搞了搞,事实上这道题不算难 ...
- ZOJ 3820:Building Fire Stations(树的直径 Grade C)
题意: n个点的树,边长全为1,求找出两个点,使得树上离这两个点距离最远的那个点,到这两个点(中某个点就行)的距离最小. 思路: 求树直径,找中点,删除中间那条边(如果直径上点数为奇数,则删任何一侧都 ...
- ZOJ 3820 Building Fire Stations
题意: 树上找两个点 使得其它点到这两点随意一点的距离的最大值最小 思路: 最大值最小 想到二分 在二分的基础上判定这个最大值是否可能 怎样判定这个问题就是怎样选那两个点的问题 非常明显 我 ...
- ZOJ Problem Set - 3820 Building Fire Stations 【树的直径 + 操作 】
题目:problemId=5374" target="_blank">ZOJ Problem Set - 3820 Building Fire Stations 题 ...
- poj2631 树的直径 + bfs
//Accepted 492 KB 0 ms //树的直径 bfs #include <cstdio> #include <cstring> #include <iost ...
- Building Fire Stations ZOJ - 3820 (二分,树的直径)
大意: 给定树, 求两个点, 使得所有其他的点到两点的最短距离的最大值尽量小. 二分答案转为判定选两个点, 向外遍历$x$的距离是否能遍历完整棵树. 取直径两段距离$x$的位置bfs即可. #incl ...
随机推荐
- spring aop advice
1.前置通知(BeforeAdvice): import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAd ...
- python学习笔记2(pycharm、数据类型)
Pycharm 的使用 IDE(Integrated Development Environ ment) :集成开发环境 Vim :经典的linux下的文本编辑器(菜鸟和大神喜欢使用) Emac ...
- ahjesus Unity3D界面快捷键
F Frame selection Tab Shift focus between first column and second column (Two columns) Ctrl/Cmd + F ...
- 【GOF23设计模式】策略模式
来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_策略模式.CRM中报价策略.GUI编程中布局管理器底层架构 package com.test.strategy; /** ...
- Virtual Environments for mac
A Virtual Environment is a tool to keep the dependencies required by different projects in separate ...
- new 小记
new运算符 能根据需求来创建对象的实例 通过与构造函数和一系列初始化过程中使用的可选参数来创建对象的实例,对象创建完成后,新创建的对象继承自构造函数的原型 function Person(name) ...
- ASP.NET MVC的请求生命周期
我希望能理解在浏览器输入URL并敲击回车来请求一个ASP.NET MVC网站的页面之后发生的任何事情. 为什么需要关心这些?有两个原因.首先是因为ASP.NET MVC是一个扩展性非常强的框架.例如, ...
- SQL 语句日期用法及函数
SQL 语句日期用法及函数 --DAY().MONTH().YEAR()——返回指定日期的天数.月数.年数:select day(cl_s_time) as '日' from class --返回天 ...
- ArcMap中的名称冲突问题
这是一个非常有趣的问题. 现在我一个点层叫"汶川73",有一个面层也叫"汶川73",使用空间连接工具来计算每个面中被落入有多少个点.但不管怎么算,结果都只能生成 ...
- C实现通用数据结构--双向链表
双向链表概述 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继next和直接前驱prev.所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结 ...