题意:

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

思路:

树的直径类题目。

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

而且要切一定切在树的直径上,如果不切在直径上,那有一个团的最场距离不就是(直径长度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. 动态DP教程

    目录 前言 开始 更进一步 前言 最后一届NOIPTG的day2T3对于动态DP的普及起到了巨大的作用.然而我到现在还不会 开始 SP1716 GSS3 - Can you answer these ...

  2. Spring Boot教程(四十二)LDAP来管理用户信息(2)

    使用spring-data-ldap的基础用法,定义LDAP中属性与我们Java中定义实体的关系映射以及对应的Repository @Data @Entry(base = "ou=peopl ...

  3. JavaWeb_(Struts2框架)Action中struts-default下result的各种转发类型

    此系列博文基于同一个项目已上传至github 传送门 JavaWeb_(Struts2框架)Struts创建Action的三种方式 传送门 JavaWeb_(Struts2框架)struts.xml核 ...

  4. Android_(控件)使用ListView显示Android系统中SD卡的文件列表

    使用ListView显示Android SD卡中的文件列表 父类布局activity_main.xml,子类布局line.xml(一个文件的单独存放) 运行截图: 程序结构: <?xml ver ...

  5. win7安装Elasticsearch和Elasticsearch-Head插件

    1.环境搭建 1)Java环境搭建可以参考相关的资料,这里不做详细介绍 2)nodejs环境搭建 到官方网站下载相应的zip包:https://nodejs.org/dist/v8.9.1/node- ...

  6. android 知识体系

  7. 强大的unique

    强大的unique 两道红题为例眼熟一下unique P1138 第k小整数 题解 这里用到了STL的去重函数哦 unique 首先你有一个待处理的数组 a[n] 一定要先排序鸭  sort( a+1 ...

  8. 执行docker run命令时报错Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

    一.解决办法: 修改host 二.步骤如下 2.1 安装dig工具  sudo apt-get install dnsutils -y (ubuntu下的安装方法) 2.2 找到registry-1. ...

  9. openerp学习笔记 计划动作、计划执行(维护计划)

    示例代码: data/scheduler.xml <?xml version="1.0" encoding="utf-8"?><openerp ...

  10. Hibernate5+Spring4整合

    (1) pom.xml <!--Spring Object/Relational Mapping --> <dependency> <groupId>org.spr ...