zoukankan      html  css  js  c++  java
  • LUOGU P4281 [AHOI2008]紧急集合 / 聚会 (lca)

    传送门

    解题思路

    可以通过手玩或打表发现,其实要选的点一定是他们三个两两配对后其中一对的$lca$上,那么就直接算出来所有的$lca$,比较大小就行了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    
    using namespace std;
    const int MAXN = 500005;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();}
        while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    
    int ans,p,n,m,head[MAXN],cnt,num;
    int to[MAXN<<1],nxt[MAXN<<1];
    int id[MAXN],dep[MAXN],top[MAXN],fa[MAXN],siz[MAXN],son[MAXN];
    
    inline void add(int bg,int ed){
        to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
    }
    
    void dfs1(int x,int f,int d){
        dep[x]=d,fa[x]=f,siz[x]=1;register int maxson=0,u;
        for(register int i=head[x];i;i=nxt[i]){
            u=to[i];if(u==f) continue;
            dfs1(u,x,d+1);siz[x]+=siz[u];
            if(siz[u]>maxson) {maxson=u;son[x]=u;}
        }
    }
    
    void dfs2(int x,int topf){
        top[x]=topf;id[x]=++num;if(!son[x]) return;dfs2(son[x],topf);int u;
        for(register int i=head[x];i;i=nxt[i]){
            u=to[i];if(u==fa[x] || u==son[x]) continue;dfs2(u,u);
        }
    }
    
    inline int lca(int x,int y){
        while(top[x]!=top[y]){
            if(dep[top[x]]>dep[top[y]]) x=fa[top[x]];
            else y=fa[top[y]];
        }
        return dep[x]>dep[y]?y:x;
    }
    
    inline void LCA(int x,int y,int z){
        register int tmp,dis,all;tmp=lca(x,y);all=lca(tmp,z);
        dis=dep[x]+dep[y]-dep[tmp]+dep[z]-2*dep[all];ans=dis;p=tmp;dis+=dep[tmp];
        tmp=lca(x,z);dis-=dep[tmp];if(ans>dis) {ans=dis;p=tmp;}
        dis+=dep[tmp];tmp=lca(y,z);dis-=dep[tmp];if(ans>dis) {ans=dis;p=tmp;}
    }
    
    void out(int x){
        if(!x) return;
        out(x/10);putchar('0'+x%10);
    }
    
    int main(){
        n=rd(),m=rd();int x,y,z;
        for(register int i=1;i<n;i++){
            x=rd(),y=rd();add(x,y),add(y,x);
        }
        dfs1(1,0,1),dfs2(1,1);
        while(m--) {
            x=rd(),y=rd(),z=rd();ans=1e9;
            LCA(x,y,z);out(p);putchar(' ');if(!ans) putchar('0');else out(ans);
            putchar('
    ');
        }     
        return 0;
    }
    View Code
  • 相关阅读:
    spring04
    kepp running 团队视频分析初步总结
    spring03
    第六周学习进度博客
    spring02
    spring初级java 应用。搭建环境。基本语法
    给定一个整数数组 nums 和一个目标值 target,求nums和为target的两个数的下表
    团队项目-运动App
    第五周学习进度博客
    java编写规范
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9768240.html
Copyright © 2011-2022 走看看