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链接. 这个题还是求最近公共祖先的问题. 而该题不同于别的题,它是需要求三个点的最近公共祖先 ...
随机推荐
- JDBC与Java数据库编程基础
一.JDBC 概述 1.什么是JDBC 称为Java数据库连接,它是一种用于数据库访问的应用程序API,由一组用Java语言编写的类和接口组成,有了JDBC就可以用同一的语法对多种关系数据库进行访问, ...
- 自己用原生JS写的轮播图,支持移动端触屏滑动,面向对象思路。分页器圆点支持click和mouseover。
自己用原生javascript写的轮播图,面向对象思路,支持移动端手指触屏滑动.分页器圆点可以选择click点击或mouseover鼠标移入时触发.图片滚动用的setInterval,感觉setInt ...
- 20145234黄斐《Java程序设计》第六周学习总结
教材学习内容总结 第十章 输入/输出 文件的读写 网络上传数据的基础 父类 InputStream与OutputStream 流(Stream)是对「输入输出」的抽象,注意「输入输出」是相对程序而言的 ...
- IoC 依赖注入容器 Unity
原文:IoC 依赖注入容器 Unity IoC 是什么? 在软件工程领域,“控制反转(Inversion of Control,缩写为IoC)”是一种编程技术,表述在面向对象编程中,可描述为在编译时静 ...
- java生成PDF,并下载到本地
1.首先要写一个PDF工具类,以及相关工具 2.PDF所需jar包 iText是一种生成PDF报表的Java组件 freemarker是基于模板来生成文本输出 <dependency> & ...
- day 4 集合
1.集合 In [1]: a = (11,22,33,11,22,33) In [2]: a Out[2]: (11, 22, 33, 11, 22, 33) #元组 In [3]: b = [11, ...
- 「国庆训练」Kingdom of Obsession(HDU-5943)
题意 给定\(s,n\),把\(s+1,s+2,...,s+n\)这\(n\)个数填到\(1,2,...,n\)里,要求\(x\)只能填到\(x\)的因子的位置(即题目中\(x\%y=0\)那么x才能 ...
- 韦大仙python--购物车
程序:购物车程序 需求: 启动程序后,让用户输入工资,然后打印商品列表 允许用户根据商品编号购买商品 用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒 可随时退出,退出时,打印已购买商品和余额 ...
- mysql bin log配置及查看
mysql执行sql可以通过设置mysql bin 日志进行记录查看 mysql bin日志配置如下: log_bin:on log_bin_basename:bin文件路径及名前缀(/var ...
- List和String数组相互转化
在工作中经常会遇到需要String[] 参数的地方,我们可以先定义一个list,再转成String[] 来使用,使用list的好处自然是可以随时方便的添加删除元素,下面是方法: List list = ...