题意:在一棵生成树上,给出了三个点,求三个点之间最大的相交点数,CF难度1900。

题解:求出三个lca,并取深度最大的那个,就是我们要的三岔路口K,然后分别求出K到a,b,c三点的路径长度,取最大值+1就是答案。为什么是取深度最大的呢?因为只有当深度是最大的时候设该点为K,这个K为三岔路口,每一个a,b,c到K的距离都不会用重复,否则如果取的不是最深的,可能造成重复的情况,这个需要避免。然后找到这个K之后,ans就是a,b,c三点分别到K的距离+1即可(+1是因为本身也算)。

一开始没做出来的原因:不知道如何找这个岔口....以为需要把岔口当做root来弄,然后就需要一次又一次的重复更新建立LCA表,就很麻烦。其实求岔口只需要以1作为root,然后a,b,c三个点两两求LCA然后取深度最大的LCA就行了....树上每2个点的距离dis(u,v)=depth[u]+depth[v]-2*depth(LCA(u,v)],好吧是我菜了

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+;
const int maxn=1e5+;
int tot,head[maxn];
struct E{
int to,next;
}edge[maxn<<];
void add(int u,int v){
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
int n,m,a[maxn],fa[maxn][],depth[maxn],vis[maxn];
void dfs(int s,int step){
depth[s]=step;vis[s]=;
for(int i=head[s];i!=-;i=edge[i].next){
int v=edge[i].to;
if(!vis[v]) fa[v][]=s,dfs(v,step+);
}
}
void bz(){
for(ll j=;j<=;j++){
for(ll i=;i<=n;i++){
fa[i][j]=fa[fa[i][j-]][j-];
}
}
}
ll LCA(ll u,ll v){
if(depth[u]<depth[v]) swap(u,v);
ll dc=depth[u]-depth[v];
for(ll i=;i<;i++){
if((<<i)&dc){
u=fa[u][i];
}
}
if(u==v) return u;
for(ll i=;i>=;i--){
if(fa[u][i]!=fa[v][i]){
u=fa[u][i];
v=fa[v][i];
}
}
u=fa[u][];
return u;
}
int dis(int u,int v){
return depth[u]+depth[v]-*depth[LCA(u,v)];
}
int main(){
scanf("%d%d",&n,&m);mem(head,-);
for(int i=;i<=n;i++){
int x;scanf("%d",&x);
add(i,x);add(x,i);
}
dfs(,);
bz();
while(m--){
int a,b,c;scanf("%d%d%d",&a,&b,&c);
int l1=LCA(a,b);
int l2=LCA(a,c);
int l3=LCA(b,c);
if(depth[l2]>depth[l1]) l1=l2;
if(depth[l3]>depth[l1]) l1=l3;
cout<<max(dis(l1,a),max(dis(l1,b),dis(l1,c)))+<<endl;
}
}

Codeforces 832D(Misha, Grisha and Underground,LCA)的更多相关文章

  1. Codeforces 832D - Misha, Grisha and Underground

    832D - Misha, Grisha and Underground 思路:lca,求两个最短路的公共长度.公共长度公式为(d(a,b)+d(b,c)-d(a,c))/2. 代码: #includ ...

  2. Codeforces 832D: Misha, Grisha and Underground 【LCA模板】

    题目链接 模板copy from http://codeforces.com/contest/832/submission/28835143 题意,给出一棵有n个结点的树,再给出其中的三个结点 s,t ...

  3. Codeforces Round #425 (Div. 2) Misha, Grisha and Underground(LCA)

    Misha, Grisha and Underground time limit per test 2 seconds memory limit per test 256 megabytes inpu ...

  4. Codeforces 832 D Misha, Grisha and Underground

    Misha, Grisha and Underground 题意:Misha 和 Grisha 是2个很喜欢恶作剧的孩子, 每天早上 Misha 会从地铁站 s 通过最短的路到达地铁站 f, 并且在每 ...

  5. Codeforecs Round #425 D Misha, Grisha and Underground (倍增LCA)

    D. Misha, Grisha and Underground time limit per test 2 seconds memory limit per test 256 megabytes i ...

  6. D. Misha, Grisha and Underground 树链剖分

    D. Misha, Grisha and Underground 这个题目算一个树链剖分的裸题,但是这个时间复杂度注意优化. 这个题目可以选择树剖+线段树,时间复杂度有点高,比较这个本身就有n*log ...

  7. Misha, Grisha and Underground CodeForces - 832D (倍增树上求LCA)

    Misha and Grisha are funny boys, so they like to use new underground. The underground has n stations ...

  8. Codeforces Round #425 (Div. 2) Problem D Misha, Grisha and Underground (Codeforces 832D) - 树链剖分 - 树状数组

    Misha and Grisha are funny boys, so they like to use new underground. The underground has n stations ...

  9. 【树链剖分】【dfs序】【LCA】【分类讨论】Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground

    一棵树,q次询问,每次给你三个点a b c,让你把它们选做s f t,问你把s到f +1后,询问f到t的和,然后可能的最大值是多少. 最无脑的想法是链剖线段树……但是会TLE. LCT一样无脑,但是少 ...

随机推荐

  1. Dockerfile的简单人门编写之关于yum的问题

    首先我们编写一个简单的Dockerfile的例子.不过再此之前大家得去把编写dockerfile的指令了解一下. 编写以 centos镜像为基础镜像,构建 http 服务,Dockerfile 要求删 ...

  2. php表格--大数据处理

    参考来源1:https://blog.csdn.net/tim_phper/article/details/77581071 参考来源2:https://blog.csdn.net/qq_376822 ...

  3. tp5.0看点

    前置操作:操作一些其他动作,例如要操作其他表格的数据啊,操作之前要有什么动作为前提或者要注意的动作. 模型事件:操作数据,例如照片的上传修改和删除. 两者的区别在于“前置操作”是动作,而“模型事件”只 ...

  4. Qt 用户通过对话框选择文件

    void class::on_pushButton_clicked() { fileFullPath = QFileDialog::getOpenFileName(this, tr("Sel ...

  5. Add text to 'Ready Page' in Inno Setup

    https://stackoverflow.com/questions/1218411/add-text-to-ready-page-in-inno-setup

  6. Android应用程序开机开机启动

    有很过情况都需要Android程序开机自启,也就是在手机开机之后马上执行相应的Android程序. 实现的方法就是,在手机开机的时候接受相应的广播,在Android程序中接受相应的广播. 第1步:建立 ...

  7. jdk 的 安装以及环境变量配置

    第一步:下载jdk 下载地址:https://www.oracle.com/technetwork/java/javase/downloads/index.html 第二步:安装jdk 第三步:配置环 ...

  8. Redis(三):多机数据库的实现

    复制 在Redis中,用户可以通过SLAVEOF命令或是slaveof选项设置服务器的主从关系,从(SLAVE)服务器会复制主(Master)服务器. 旧版复制功能实现(2.8以前) 旧版复制功能主要 ...

  9. Microsoft Dynamics CRM 2015 服务器系统的性能维护,追踪, 也可以用到任务管理器哟...

    Microsoft Dynamics CRM 2015 的追踪是一个很有用的function,它能为我们的CRM调试,评估 提供有价值的信息:我们可以用window的性能监控工具来了解CRM的性能状态 ...

  10. Linux shell基础(五)sed命令

    一.sed命令 sed是一种强大的流式编辑器 (stream editor for filtering and transforming text),它能够完美的使用正则表达式,逐行处理文本并把结果显 ...