题意:

给你一颗树,让你放两个点,放在哪里的时候任意点到某个最近的消防站最远值最小。

思路:

树的直径类题目。

首先我们想两个点会把整棵树分成两个团,所以肯定会在树的某个链上切开。

而且要切一定切在树的直径上,如果不切在直径上,那有一个团的最场距离不就是(直径长度lenth/2了吗)。

所以我们取出直径,枚举切在哪里。

左右两半边的计算方法是一样的,如下图:

我们先算出直径上每个节点的最长距离,因为对于某一个节点,它的分支的长度它到不会超过到直径两端的长度,这样我们就很好算了。

跑两遍:第一次从左到右对左半边的团的直径前缀记录下来,第二次从右到左对右半边的直径后缀记录下来

(注意:1. 对lenth取max,2. 如果直径是偶数如:8,lenth要记为5,mid+1)

最后再跑一遍记录答案就行了。

 #define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#include <cstdio>//sprintf islower isupper
#include <cstdlib>//malloc exit strcat itoa system("cls")
#include <iostream>//pair
#include <fstream>//freopen("C:\\Users\\13606\\Desktop\\草稿.txt","r",stdin);
#include <bitset>
//#include <map>
//#include<unordered_map>
#include <vector>
#include <stack>
#include <set>
#include <string.h>//strstr substr
#include <string>
#include <time.h>//srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
#include <cmath>
#include <deque>
#include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
#include <vector>//emplace_back
//#include <math.h>
//#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
#include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
#define fo(a,b,c) for(register int a=b;a<=c;++a)
#define fr(a,b,c) for(register int a=b;a>=c;--a)
#define mem(a,b) memset(a,b,sizeof(a))
#define pr printf
#define sc scanf
#define ls rt<<1
#define rs rt<<1|1
typedef long long ll;
void swapp(int &a,int &b);
double fabss(double a);
int maxx(int a,int b);
int minn(int a,int b);
int Del_bit_1(int n);
int lowbit(int n);
int abss(int a);
//const long long INF=(1LL<<60);
const double E=2.718281828;
const double PI=acos(-1.0);
const int inf=(<<);
const double ESP=1e-;
const int mod=(int)1e9+;
const int N=(int)1e6+; int n; bool vis[N];
vector<vector<int> >G(N);
struct node{int now,val;};
void Init()
{
for(int i=;i<=n;++i)
vis[i]=;
}
int Val_bfs(node start)
{
int ans=;
queue<node>q;
q.push(start);
while(!q.empty())
{
node v=q.front();q.pop();
ans=max(ans,v.val);
vis[v.now]=;
int sz=G[v.now].size();
for(int i=;i<sz;++i)
{
int to=G[v.now][i];
if(!vis[to])
q.push({to,v.val+});
}
}
return ans;
} int Start,End;
void queue_dfs1(node start)
{
Init();
int max_=;
queue<node>q;
q.push(start);
while(!q.empty())
{
node v=q.front();q.pop();
vis[v.now]=;
if(max_<v.val)max_=v.val,Start=v.now;
int sz=G[v.now].size();
for(int i=;i<sz;++i)
{
int to=G[v.now][i];
if(!vis[to])
q.push({to,v.val+});
}
}
}
int fa[N];
void queue_dfs2()
{
for(int i=;i<=n;++i)fa[i]=;
Init();
int max_=;
queue<node>q;
q.push({Start,});
while(!q.empty())
{
node v=q.front();q.pop();
vis[v.now]=;
if(max_<v.val)max_=v.val,End=v.now;
int sz=G[v.now].size();
for(int i=;i<sz;++i)
{
int to=G[v.now][i];
if(!vis[to])
q.push({to,v.val+}),fa[to]=v.now;
}
}
}
int Line[N];
int get_line()
{
Init();
int pos=End;
int cnt=;
while(fa[pos])
Line[++cnt]=pos,vis[Line[cnt]]=,pos=fa[pos];
Line[++cnt]=pos,vis[Line[cnt]]=;
return cnt;
}
int Val[N];
struct mark
{
int L,p1;
}memery[N],memery2[N];
void solve(int cnt)
{
int p1;
for(int i=;i<=cnt;++i)
Val[i]=Val_bfs({Line[i],});
memery[]=memery2[cnt+]={-,-};
for(int i=;i<=cnt-;++i)
{
int lenth=(Val[i]+i+)/;
if((Val[i]+i)%==)
lenth++;
p1=Line[lenth];
if(lenth<memery[i-].L)
memery[i]=memery[i-];
else
memery[i]={lenth,p1};
}
int p2;
for(int i=cnt;i>=;--i)
{
int lenth=(Val[i]+cnt+-i+)/;
if((Val[i]+cnt+-i)%==)
lenth++;
p2=Line[cnt+-lenth];
if(lenth<memery2[i+].L)
memery2[i]=memery2[i+];
else
memery2[i]={lenth,p2};
}
int L=inf,P1,P2;
for(int i=;i<=cnt-;++i)
{
if(L>max(memery[i].L,memery2[i+].L))
L=max(memery[i].L,memery2[i+].L),P1=memery[i].p1,P2=memery2[i+].p1;
}
pr("%d %d %d\n",L-,P1,P2);
} int main()
{
// freopen("C:\\Users\\13606\\Desktop\\草稿.txt","r",stdin);
int T;
sc("%d",&T);
while(T--)
{
sc("%d",&n);
for(int i=;i<=n;++i)
G[i].clear();
for(int i=;i<=n-;++i)
{
int u,v;
sc("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
queue_dfs1({,});
queue_dfs2();
int lenth=get_line();
solve(lenth);
}
return ;
} /**************************************************************************************/ int maxx(int a,int b)
{
return a>b?a:b;
} void swapp(int &a,int &b)
{
a^=b^=a^=b;
} int lowbit(int n)
{
return n&(-n);
} int Del_bit_1(int n)
{
return n&(n-);
} int abss(int a)
{
return a>?a:-a;
} double fabss(double a)
{
return a>?a:-a;
} int minn(int a,int b)
{
return a<b?a:b;
}

树上选两点(使最短)树的直径+bfs的更多相关文章

  1. Codeforces 1182D Complete Mirror 树的重心乱搞 / 树的直径 / 拓扑排序

    题意:给你一颗树,问这颗树是否存在一个根,使得对于任意两点,如果它们到根的距离相同,那么它们的度必须相等. 思路1:树的重心乱搞 根据样例发现,树的重心可能是答案,所以我们可以先判断一下树的重心可不可 ...

  2. poj2631 树的直径 + bfs

    //Accepted 492 KB 0 ms //树的直径 bfs #include <cstdio> #include <cstring> #include <iost ...

  3. 从Trie树(字典树)谈到后缀树

    转:http://blog.csdn.net/v_july_v/article/details/6897097 引言 常关注本blog的读者朋友想必看过此篇文章:从B树.B+树.B*树谈到R 树,这次 ...

  4. java实现哈弗曼树和哈夫曼树压缩

    本篇博文将介绍什么是哈夫曼树,并且如何在java语言中构建一棵哈夫曼树,怎么利用哈夫曼树实现对文件的压缩和解压.首先,先来了解下什么哈夫曼树. 一.哈夫曼树 哈夫曼树属于二叉树,即树的结点最多拥有2个 ...

  5. 树&二叉树&哈夫曼树

    1.树 需要注意的两点:n(n>=0)表示结点的个数,m表示子树的个数 (1)n>0时,树的根节点是唯一的. (2)m>0时,子树的个数没有限制. 结点的度和树的度 (1)结点的度是 ...

  6. [算法]从Trie树(字典树)谈到后缀树

    我是好文章的搬运工,原文来自博客园,博主July_,地址:http://www.cnblogs.com/v-July-v/archive/2011/10/22/2316412.html 从Trie树( ...

  7. BZOJ1146[CTSC2008]网络管理——出栈入栈序+树状数组套主席树

    题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条 ...

  8. [转]B树(多向平衡查找树)详解

    B-树是对2-3树数据结构的扩展.它支持对保存在磁盘或者网络上的符号表进行外部查找,这些文件可能比我们以前考虑的输入要大的多(以前的输入能够保存在内存中). (B树和B+树是实现数据库的数据结构,一般 ...

  9. 树-二叉搜索树-AVL树

    树-二叉搜索树-AVL树 树 树的基本概念 节点的度:节点的儿子数 树的度:Max{节点的度} 节点的高度:节点到各叶节点的最大路径长度 树的高度:根节点的高度 节点的深度(层数):根节点到该节点的路 ...

随机推荐

  1. Vue_(基础)Vue中的事件

    Vue.js中文文档 传送门 Vue@事件绑定 v-show:通过切换元素的display CSS属性实现显示隐藏: v-if:根据表达式的真假实现显示隐藏,如果隐藏,它绑定的元素都会销毁,显示的时候 ...

  2. flask第二篇 三剑客+特殊返回值

    1.Flask中的HTTPResponse 在Flask 中的HttpResponse 在我们看来其实就是直接返回字符串 2.Flask中的Redirect 每当访问"/redi" ...

  3. 代码审计之seacms v6.54 前台Getshell 复现分析

    1.环境: php5.5.38+apache+seacms v6.54 上一篇文章针对seacms v6.45 进行了分析,官方给出针对修复前台geishell提供的方法为增加: $order = ( ...

  4. LeetCode 6. Z字形变换(ZigZag Conversion)

    题目描述 将字符串 "PAYPALISHIRING" 以Z字形排列成给定的行数: P A H N A P L S I I G Y I R 之后从左往右,逐行读取字符:"P ...

  5. redux异步

    在一个项目中 redux 是必不可少的,redux 中没有提供异步的操作,但是异步又是项目开发中重要的一部分,所以我们的 redux 对此有进行了拓展: 所以我们需要 redux-thunk 的插件, ...

  6. AppiumLibrary移动APP测试

    使用Genymotion模拟器结合RF执行 前提搭建环境参考<python_Appium测试环境搭建>文章详细介绍. 常用关键字 关  键  字 描   述 Click Button 点击 ...

  7. IDEA内存设置

    之前,博主的idea一直运行正常,今天,开发了一个接口,因为接口在项目中另一个模块,之前从来没有启动过这个模块,由于调试接口将该模块也放到tomcat容器中,结果我的idea不停崩溃,于是查看idea ...

  8. 本地oracle可以通过localhost连接,无法通过ip地址连接解决方法,oracle远程连接配置

    Oracle11g安装后只有本地可以连接,远程无法连接,而且本地只能配置成localhost配置成IP地址也无法连接. 这是因为安装oracle的时候没有配置远程的监听,默认的监听是localhost ...

  9. 小D课堂 - 新版本微服务springcloud+Docker教程_1_02技术选型

    笔记 2.技术选型和学后水平     简介:课程所需基础和技术选型讲解,学完课程可以到达怎样的程度,          1.IDEA JDK8 Maven SpringBoot基础 Linux 2.理 ...

  10. spring boot 启动报 java.lang.NoClassDefFoundError: ch/qos/logback/core/spi/LifeCycle 错误

    Failed to instantiate SLF4J LoggerFactory Reported exception: java.lang.NoClassDefFoundError: ch/qos ...