转换成抽象模型,就是要求一棵树(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)的更多相关文章

  1. BZOJ 1787 紧急集合

    LCA.注意细节. #include<iostream> #include<cstdio> #include<cstring> #include<algori ...

  2. 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 ...

  3. 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 ...

  4. bzoj 1787: [Ahoi2008]Meet 紧急集合【树链剖分lca】

    对于三个点求最小路径长度和,答案肯定在某两个点的lca上,因为如果把集合点定在公共lca上,一定有两个点汇合后再一起上到lca,这样显然不如让剩下的那个点下来 这个lca可能是深度最深的--但是我懒得 ...

  5. bzoj 1787 && bzoj 1832: [Ahoi2008]Meet 紧急集合(倍增LCA)算法竞赛进阶指南

    题目描述 原题连接 Y岛风景美丽宜人,气候温和,物产丰富. Y岛上有N个城市(编号\(1,2,-,N\)),有\(N-1\)条城市间的道路连接着它们. 每一条道路都连接某两个城市. 幸运的是,小可可通 ...

  6. bzoj 1787 [Ahoi2008]Meet 紧急集合(1832 [AHOI2008]聚会)

    1787: [Ahoi2008]Meet 紧急集合 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1841  Solved: 857[Submit][ ...

  7. BZOJ 1787: [Ahoi2008]Meet 紧急集合( 树链剖分 )

    这道题用 LCA 就可以水过去 , 但是我太弱了 QAQ 倍增写LCA总是写残...于是就写了树链剖分... 其实也不难写 , 线段树也不用用到 , 自己YY一下然后搞一搞就过了...速度还挺快的好像 ...

  8. 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 ...

  9. bzoj 1787 Meet 紧急集合

    Meet 紧急集合 这个题是在脖子oj(清北某奆佬给起的名字)八中oj(大视野在线评测)上的. 给出bzoj链接. 这个题还是求最近公共祖先的问题. 而该题不同于别的题,它是需要求三个点的最近公共祖先 ...

随机推荐

  1. java 第八章 异常处理

    一.异常简介 (一)定义: 运行期间出现的错误,而不是编译时的语法错误 例如: 1.打开一个不存在的文件 2.网络连接中断 3.数学类错误 4.操作数组越界等 (二)异常的继承树 (三)异常类的体系结 ...

  2. android学习七 菜单

    1.菜单分类 常规菜单 子菜单 上下文菜单 图标菜单 辅助菜单 交替菜单 2.菜单类 andriod.view.menu   3.菜单的参数     名称:字符串标题     菜单ID:整数     ...

  3. ToString的格式化字符串

    如下: , , ).ToString(@"d\.hh\:mm\:ss"); var b = DateTimeOffset.Now.ToString("yyyy-MM-dd ...

  4. hdu1730Northcott Game(nim博弈)

    Northcott Game Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  5. jdk从1.8换成1.7后,查看版本还是1.8解决方法

    因学习需要,需将jdk从1.8更改到1.7,其中遇到了些小麻烦,如果你也遇到这种麻烦,可以借鉴一下我的解决方法. 1.jdk的安装及环境变量的配置,详见https://jingyan.baidu.co ...

  6. JS实现对数组的去重

    JS实现对数组的去重 $scope.validateContect = function(text) { var arr = text; // 若传入的数据为string类型,用逗号分隔 if((ty ...

  7. 【input】输入框组件说明

    input输入框组件 原型: <input value="[String]" type="[text | number | idcard | digit]" ...

  8. Python字符串所有操作函数

    name = "my \tname is {name} and i am {year} old" print(name.capitalize())#首字母大写 print(name ...

  9. c字符指针与字符数组的区别

    1.定义 char *pchar;  //定义了指针,没赋值之前不能使用.如果:printf("*pchar:%c\n",*pchar); 出现段错误Segmentation fa ...

  10. Docker学习笔记总结

    Docker学习笔记 https://yeasy.gitbooks.io/docker_practice/content/   一 环境搭建 Ubuntu安装 .添加软件源的GPG密钥 curl -f ...