• bzoj1787 紧急集合


    传送门

    题目

    Input

    Output

    分析

    看到这个题不难想到倍增LCA,然后我们考虑如何计算。我们分别求出3个点中任意两点的LCA,为了走的步数最少所以肯定是先有两个点相遇然后另一个点走的它们相遇的点,至于最后的距离自己画一画就知道啦。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    #define ri register int
    const int LOG=18; 
    int pr[600000][LOG+3],dep[600000],cnt;
    int head[1200000],to[1200000],nxt[1200000];
    inline int read(){
          int x=0,f=1;char s=getchar();
          while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
          while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+(s-'0');s=getchar();}
          return x*f;
    }
    inline void add(int x,int y){
          to[++cnt]=y;
          nxt[cnt]=head[x];
          head[x]=cnt;
          to[++cnt]=x;
          nxt[cnt]=head[y];
          head[y]=cnt;
    }
    inline void dfs(int x,int fa){
          pr[x][0]=fa;
          for(ri i=head[x];i;i=nxt[i])
             if(to[i]!=fa){
               dep[to[i]]=dep[x]+1;
               dfs(to[i],x);
             }
    }
    inline int lca(int x,int y){
          if(dep[y]>dep[x])swap(x,y);
          int ans=0;
          for(ri i=LOG;i>=0;--i)
            if(dep[x]-(1<<i)>=dep[y])
              x=pr[x][i];
          if(x==y)return x;
          for(ri i=LOG;i>=0;--i)
            if(pr[x][i]!=pr[y][i]){
              x=pr[x][i];
              y=pr[y][i];
            }
          return pr[x][0];
    }
    int main()
    {     int n,m,x,y,z;
          n=read(),m=read();
          for(ri i=1;i<n;++i){
              x=read(),y=read();
              add(x,y);
          }
          dep[1]=1;
          dfs(1,0);
          for(ri j=1;j<=LOG;++j)
            for(ri i=1;i<=n;++i)
              pr[i][j]=pr[pr[i][j-1]][j-1];
          for(ri i=1;i<=m;++i){
              x=read(),y=read(),z=read();
              int a1=lca(x,y),a2=lca(x,z),a3=lca(y,z),ans;
              if(a1==a2)ans=a3;
                else if(a1==a3)ans=a2;
                else if(a2==a3)ans=a1;
              printf("%d %d
    ",ans,dep[x]+dep[y]+dep[z]-dep[a1]-dep[a2]-dep[a3]);
          }
          return 0;
    }
  • 相关阅读:
    Windows异常处理机制介绍
    OD 与 Win7
    对VC6编译优化的简单测试
    QQ版本号(2012/07/22 更新)
    OD与调试符号
    Balsamiq Mockups
    hotpatch热修补
    QQ
    VC的编译开关参数大全
    隐藏秘技:vc输出类的layout信息
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9205457.html
Copyright © 2020-2023  润新知