zoukankan      html  css  js  c++  java
  • HYSBZ 1787 Meet 紧急集合

    题意:
    给定一些点和连通它们的边,三个人在站在不同的点上,要集合到同一点上去,问最小的总步数
    题解:
    ①一个关于LCA的题
    ②记住一个结论:三个点的最小距离点等于两两的LCA中与其他两个LCA不同的LCA
    ③然后就没了

    #pragma GCC optimize (2)
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define maxn 500010
    #define abs(x) ((x)>0?(x):-(x))
    using namespace std;
    struct Edge{
            int to,next;
    }a[maxn<<1];
    int n,m;
    int head[maxn],cnt;
    int deep[maxn],prt[maxn],size[maxn],son[maxn];
    int Time,Dfn[maxn],pos[maxn],top[maxn];
    void Init();
    void Insert(int,int);
    void DFS1(int,int,int);
    void DFS2(int,int);
    int LCA(int,int);
    void Solve(int,int,int);
    int Dis(int,int);
    signed main(){
            // freopen("in.cpp","r",stdin);
            Init();
            return 0;
    }
    void Init(){
            scanf("%d%d",&n,&m);
            int x,y,z;
            for(int i=1;i<n;i++){
                    scanf("%d%d",&x,&y);
                    Insert(x,y);Insert(y,x);
            }
            DFS1(1,0,1);
            DFS2(1,1);
            while(m--){
                    scanf("%d%d%d",&x,&y,&z);
                    Solve(x,y,z);
            }
    }
    void Solve(int x,int y,int z){
            int a=LCA(x,y),b=LCA(x,z),c=LCA(y,z);
            int prt;
            if(a==b)prt=c;
            else if(a==c)prt=b;
            else prt=a;
            printf("%d %d
    ",prt,Dis(x,prt)+Dis(y,prt)+Dis(z,prt));
    }
    int Dis(int x,int y){
            int prt=LCA(x,y);
            return deep[x]+deep[y]-2*deep[prt];
    }
    void Insert(int x,int y){
            a[++cnt].to=y;
            a[cnt].next=head[x];
            head[x]=cnt;
    }
    void DFS1(int x,int prt,int deep){
            ::deep[x]=deep;
            ::prt[x]=prt;
            ::size[x]=1;
            for(int i=head[x];i;i=a[i].next){
                    int y=a[i].to;
                    if(y==prt)continue;
                    DFS1(y,x,deep+1);
                    size[x]+=size[y];
                    if(size[y]>size[son[x]])son[x]=y;
            }
    }
    void DFS2(int x,int top){
            ::Dfn[x]=++Time;
            ::top[x]=top;
            ::pos[Time]=x;
            if(son[x])DFS2(son[x],top);
            for(int i=head[x];i;i=a[i].next){
                    int y=a[i].to;
                    if(y==prt[x]||y==son[x])continue;
                    DFS2(y,y);
            }
    }
    int LCA(int x,int y){
            while(top[x]!=top[y]){
                    if(deep[top[x]]<deep[top[y]])std::swap(x,y);
                    x=prt[top[x]];
            }
            if(deep[x]<deep[y])return x;
            return y;
    }

  • 相关阅读:
    [滤镜]的firefox兼容问题
    软件编程中的21条法则
    程序员!你应该读别人的心得,但是一定要自己注解
    致橡树——舒婷
    高级动物
    终于把网站最后一个模块了结了
    终于解决了网站程序中的问题
    北京杂种
    博客园驻小窝
    Eval函数
  • 原文地址:https://www.cnblogs.com/holy-unicorn/p/9510220.html
Copyright © 2011-2022 走看看