BZOJ 1787 紧急集合(LCA)
转换成抽象模型,就是要求一棵树(N个点,有N-1条边表示这个图是棵树)中某一点满足给定三点a,b,c到某一点的距离和最小。那么我们想到最近公共祖先的定义,推出只有集合点在LCA(a,b)、LCA(a,c)、LCA(b,c)中,才能保证距离和最近。
# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi 3.1415926535
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... struct Edge{int to, next;}edge[N<<];
int head[N], tot, fa[N][], deg[N];
queue<int>que; void add_edge(int u, int v){edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++;}
void init(){tot=; mem(head,-);}
void BFS(int root){
deg[root]=; fa[root][]=root; que.push(root);
while (!que.empty()) {
int tmp=que.front(); que.pop();
FO(i,,) fa[tmp][i]=fa[fa[tmp][i-]][i-];
for (int i=head[tmp]; i!=-; i=edge[i].next) {
int v=edge[i].to;
if (v==fa[tmp][]) continue;
deg[v]=deg[tmp]+; fa[v][]=tmp; que.push(v);
}
}
}
int LCA(int u, int v){
if (deg[u]>deg[v]) swap(u,v);
int hu=deg[u], hv=deg[v], tu=u, tv=v;
for (int det=hv-hu, i=; det; det>>=, i++) if (det&) tv=fa[tv][i];
if (tu==tv) return tu;
for (int i=; i>=; --i) {
if (fa[tu][i]==fa[tv][i]) continue;
tu=fa[tu][i]; tv=fa[tv][i];
}
return fa[tu][];
}
int main ()
{
int n, m, u, v, w, x, y, tmp, p;
init();
n=Scan(); m=Scan();
FO(i,,n) scanf("%d%d",&u,&v), add_edge(u,v), add_edge(v,u);
BFS();
while (m--) {
int ans=INF;
scanf("%d%d%d",&u,&v,&w);
x=LCA(u,v); tmp=deg[u]+deg[v]-*deg[x];
y=LCA(x,w); tmp+=(deg[x]+deg[w]-*deg[y]);
if (ans>tmp) p=x, ans=tmp;
x=LCA(u,w); tmp=deg[u]+deg[w]-*deg[x];
y=LCA(x,v); tmp+=(deg[x]+deg[v]-*deg[y]);
if (ans>tmp) p=x, ans=tmp;
x=LCA(v,w); tmp=deg[v]+deg[w]-*deg[x];
y=LCA(x,u); tmp+=(deg[x]+deg[u]-*deg[y]);
if (ans>tmp) p=x, ans=tmp;
printf("%d %d\n",p,ans);
}
return ;
}
复杂度O(n+m*logn).
BZOJ 1787 紧急集合(LCA)的更多相关文章
- BZOJ 1787 紧急集合
LCA.注意细节. #include<iostream> #include<cstdio> #include<cstring> #include<algori ...
- BZOJ 1787: [Ahoi2008]Meet 紧急集合 LCA
1787: [Ahoi2008]Meet 紧急集合 Description Input Output Sample Input 6 4 1 2 2 3 2 4 4 5 5 6 4 5 6 6 3 1 ...
- BZOJ 1787: [Ahoi2008]Meet 紧急集合(lca+贪心)
[Ahoi2008]Meet 紧急集合 Description Input Output Sample Input 6 4 1 2 2 3 2 4 4 5 5 6 4 5 6 6 3 1 2 4 4 ...
- bzoj 1787: [Ahoi2008]Meet 紧急集合【树链剖分lca】
对于三个点求最小路径长度和,答案肯定在某两个点的lca上,因为如果把集合点定在公共lca上,一定有两个点汇合后再一起上到lca,这样显然不如让剩下的那个点下来 这个lca可能是深度最深的--但是我懒得 ...
- bzoj 1787 && bzoj 1832: [Ahoi2008]Meet 紧急集合(倍增LCA)算法竞赛进阶指南
题目描述 原题连接 Y岛风景美丽宜人,气候温和,物产丰富. Y岛上有N个城市(编号\(1,2,-,N\)),有\(N-1\)条城市间的道路连接着它们. 每一条道路都连接某两个城市. 幸运的是,小可可通 ...
- bzoj 1787 [Ahoi2008]Meet 紧急集合(1832 [AHOI2008]聚会)
1787: [Ahoi2008]Meet 紧急集合 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 1841 Solved: 857[Submit][ ...
- BZOJ 1787: [Ahoi2008]Meet 紧急集合( 树链剖分 )
这道题用 LCA 就可以水过去 , 但是我太弱了 QAQ 倍增写LCA总是写残...于是就写了树链剖分... 其实也不难写 , 线段树也不用用到 , 自己YY一下然后搞一搞就过了...速度还挺快的好像 ...
- bzoj 1787: [Ahoi2008]Meet 紧急集合
1787: [Ahoi2008]Meet 紧急集合 Description Input Output Sample Input 6 4 1 2 2 3 2 4 4 5 5 6 4 5 6 6 3 1 ...
- bzoj 1787 Meet 紧急集合
Meet 紧急集合 这个题是在脖子oj(清北某奆佬给起的名字)八中oj(大视野在线评测)上的. 给出bzoj链接. 这个题还是求最近公共祖先的问题. 而该题不同于别的题,它是需要求三个点的最近公共祖先 ...
随机推荐
- Tomcat7 调优及 JVM 参数优化
Tomcat 的缺省配置是不能稳定长期运行的,也就是不适合生产环境,它会死机,让你不断重新启动,甚至在午夜时分唤醒你.对于操作系统优化来说,是尽可能的增大可使用的内存容量.提高CPU 的频率,保证 ...
- POJ2505 A multiplication game(博弈)
题意 开始时$p = 1$,每次可以乘$2 - 9$,第一个使得$p \geqslant n$的人赢 问先手是否必胜 $1 <n <4294967295$ Sol 认真的推理一波. 若当前 ...
- TensorFlow:在PyCharm中配置TensorFlow
在本地配置好TensorFlow后,如何在PyCharm中配置TensorFlow呢? 只需将当前的Python编译环境配置为TensFlow安装路径中的Pyhton环境,具体操作如下: 1. 打开‘ ...
- LeetCode:39. Combination Sum(Medium)
1. 原题链接 https://leetcode.com/problems/combination-sum/description/ 2. 题目要求 给定一个整型数组candidates[ ]和目标值 ...
- Spring全局变量
压测spring框架的webservice接口,大并发量下响应值与预期值不一致 经查,开发在类中使用全局变量导致: springmvc核心控制器DispatcherServlet 默认为每个contr ...
- 【SpringCloud】 第十篇: 高可用的服务注册中心
前言: 必需学会SpringBoot基础知识 简介: spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选. ...
- Python入门编程中的变量、字符串以及数据类型
//2018.10.10 字符串与变量 1. 在输出语句中如果需要出现单引号或者双引号,可以使用转义符号\,它可以将其中的歧义错误解释化解,使得输出正常: 2. 对于python的任何变量都需要进行赋 ...
- appium关键字:
## Appium 服务关键字 <expand_table> |关键字|描述|实例||----|-----------|-------||`automationName`|你想使用的自动化 ...
- Java进阶知识点: 枚举值
Java进阶知识点1:白捡的扩展性 - 枚举值也是对象 一.背景 枚举经常被大家用来储存一组有限个数的候选常量.比如下面定义了一组常见数据库类型: public enum DatabaseType ...
- 剑指offer-栈的压入弹出序列21
题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压 ...