zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    HashMap按键排序和按值排序
    LeetCode 91. Decode Ways
    LeetCode 459. Repeated Substring Pattern
    JVM
    LeetCode 385. Mini Parse
    LeetCode 319. Bulb Switcher
    LeetCode 343. Integer Break
    LeetCode 397. Integer Replacement
    LeetCode 3. Longest Substring Without Repeating Characters
    linux-网络数据包抓取-tcpdump
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9205457.html
Copyright © 2011-2022 走看看