首页 > 其他 > 详细

【刷题】【LCA】紧急集合/聚会

时间:2019-10-13 22:27:45      阅读:96      评论:0      收藏:0      [点我收藏+]

给你一棵树,求三个点到哪个点的距离和最近,且求出距离

挺好证的,是三个LCA中矮的那个,

但是这题需要卡常技巧,QAQ

以后还是要养成加上卡常技巧的习惯,20分啊

技术分享图片
#include<cstdio>
#include<cstdlib>
#include<vector>
using namespace std;
int n,m;
const int N=500003;
int tot,head[N];
struct node
{
    int v,nx;
}e[N<<1];
void add(int u,int v)
{
    e[++tot].v =v,e[tot].nx =head[u],head[u]=tot;
    e[++tot].v =u,e[tot].nx =head[v],head[v]=tot;
}
int fa[N][20],dep[N];

inline int read()
{
    int x=0;char c=getchar();
    while(c<0 || c>9) c=getchar();
    while(c>=0&&c<=9) x=(x<<1)+(x<<3)+c-0,c=getchar();
    return x;
}

void dfs(int rt,int f)
{
    dep[rt]=dep[f]+1;
    fa[rt][0]=f;
    for(int i=1;i<20 && fa[rt][i-1];i++)
        fa[rt][i]=fa[fa[rt][i-1]][i-1];
    
    for(int i=head[rt];i;i=e[i].nx )
        if(e[i].v !=f) 
            dfs(e[i].v ,rt);
}
int LCA(int x,int y)
{
    if(dep[x]<dep[y])
        x+=y,y=x-y,x-=y;
    int dis=dep[x]-dep[y];
    for(int i=1,j=0;i<=dis;i<<=1,j++)
        if(dis&i) x=fa[x][j];
    if(x==y) return x;
    
    for(int i=19;~i;i--)
        if(fa[x][i]!=fa[y][i])
            x=fa[x][i],y=fa[y][i]; 
    return fa[x][0];
}

int main()
{
    n=read(),m=read();
    int u,v,w;
    for(int i=1;i<n;i++)
        u=read(),v=read(),add(u,v);
    dfs(1,0);   
    
    while(m--)
    {
        u=read(),v=read(),w=read();
        int a=LCA(u,v),b=LCA(u,w),c=LCA(v,w);
        
        int ans=dep[u]+dep[v]+dep[w],pos;
        if(dep[a]==dep[b] ) 
            ans-=dep[a]*2+dep[c],pos=c;
        else if(dep[a]==dep[c])
            ans-=dep[a]*2+dep[b],pos=b;
        else ans-=dep[b]*2+dep[a],pos=a;
        printf("%d %d\n",pos,ans);
    }
    
    return 0;
} 
View Code

 

【刷题】【LCA】紧急集合/聚会

原文:https://www.cnblogs.com/xwww666666/p/11668461.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!