bzoj 1787(LCA)
来源:互联网 发布:淘宝批量修改宝贝描述 编辑:程序博客网 时间:2024/05/16 18:42
传送门
题意:一棵树 N 个结点的树,有 M 次查询:树上三个点到哪个点的距离之和最小。
题解:
求(a,b)(b,c)(c,a)三对点的LCA,深度最深的那个即使答案:
下面口胡一下证明过程:
三个LCA如果发生重合,那么显然上述做法正确,不再赘述。
如果三个LCA互不相同,那么它们一定可以组成一个二叉结构,从将最浅的LCA作为答案,将其往另外两个移动,每移动一次距离之和+1-2。显然移动到最深的那个LCA可以最小化距离之和,到达最深LCA后若再移动则反而会增大距离之和,所以最深LCA即所求点。
P.S.为数不多的本蒟蒻卡不下来的大常数代码,估计跑得比我快1/3的都是tarjan求LCA而非倍增。
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAXN=5e5+4;int head[MAXN],etot=0;struct EDGE {int v,nxt;}e[MAXN<<1];int n,m,f[20][MAXN],dep[MAXN]={0};inline int read() {int x=0;char c=getchar();while (c<'0'||c>'9') c=getchar();while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();return x;}inline void adde(int u,int v) {e[etot].nxt=head[u],e[etot].v=v,head[u]=etot++;e[etot].nxt=head[v],e[etot].v=u,head[v]=etot++;}void dfs(int p,int fa) {dep[p]=dep[fa]+1,f[0][p]=fa;for (int i=head[p];~i;i=e[i].nxt) {int v=e[i].v;if (v^fa) dfs(v,p);}}inline void da() {for (int j=1;(1<<j)<=n;++j)for (register int i=1;i<=n;++i)f[j][i]=f[j-1][f[j-1][i]];}inline int LCA(int x,int y) {if (dep[x]<dep[y]) x^=y^=x^=y;int t=dep[x]-dep[y];for (int i=0;i<20;++i)if (t&(1<<i)) x=f[i][x];if (x==y) return x;for (int i=19;~i;--i)if (f[i][x]^f[i][y]) x=f[i][x],y=f[i][y];return f[0][x];}inline int dis(int x,int y) {return dep[x]+dep[y]-(dep[LCA(x,y)]<<1);}int main() {//freopen("bzoj 1787.in","r",stdin);memset(head,-1,sizeof(head));n=read(),m=read();for (register int i=1;i<n;++i) {int u=read(),v=read();adde(u,v);}dfs(1,0);da();for (register int t=0;t<m;++t) {int a=read(),b=read(),c=read();int x=LCA(a,b),y=LCA(b,c),z=LCA(c,a);if (dep[x]>=dep[y]&&dep[x]>=dep[z]) {printf("%d %d\n",x,dep[a]-dep[x]+dep[b]-dep[x]+dis(x,c));continue;}if (dep[y]>=dep[x]&&dep[y]>=dep[z]) {printf("%d %d\n",y,dep[b]-dep[y]+dep[c]-dep[y]+dis(y,a));continue;}if (dep[z]>=dep[x]&&dep[z]>=dep[y]) {printf("%d %d\n",z,dep[c]-dep[z]+dep[a]-dep[z]+dis(z,b));continue;}}return 0;}
阅读全文
0 0
- bzoj 1787(LCA)
- BZOJ 1787 裸LCA
- bzoj 1787 lca
- bzoj 3732(kruskal+LCA)
- bzoj 1787: [Ahoi2008]Meet 紧急集合 (LCA)
- bzoj 1787 && bzoj 1832: [Ahoi2008]Meet 紧急集合(倍增LCA)
- BZOJ 1787 AHOI2008 紧急集合 倍增LCA
- BZOJ 1787: [Ahoi2008]Meet 紧急集合(LCA)
- bzoj 1787: [Ahoi2008]Meet 紧急集合(lca)
- [AHOI2008] BZOJ 1787 Meet紧急集合-LCA
- 【BZOJ】1787 [Ahoi2008]Meet 紧急集合 LCA
- BZOJ 1787 Meet 紧急集合 (LCA)
- bzoj 1787: [Ahoi2008]Meet 紧急集合 lca
- BZOJ 1787: [Ahoi2008]Meet 紧急集合【LCA】
- 倍增LCA(bzoj 3732: Network)
- bzoj 3910(LCA+并查集)
- bzoj 4390(LCA+差分)
- *【bzoj 1602】牧场行走(LCA)
- JPA 各种实体锁模式的区别
- RSA密钥长度、明文长度和密文长度
- spring ioc是如何实现的
- Eclipse中使用Tomcat Plugin启动Tomcat时的常用配置
- iPhone X适配
- bzoj 1787(LCA)
- EBS多路电话网关调试
- 2、java多线程--利用BlockingQueue实现生产者消费者模型
- vim 的简单配置
- Git基础知识
- 杂乱知识点
- js数据类型
- 在回调API提供方不确定提供数据的形式的时候,判断数据是怎么提交过来的
- Java