zoukankan      html  css  js  c++  java
  • bzoj 1832: [AHOI2008]聚会

    良心题2333

    三个点两两求一遍就行,最小肯定是在某2个点的lca处,(肯定让第三个人去找2个人,不能让2个人一起去找第三个人233)

     1 #include<bits/stdc++.h>
     2 #define N 500005
     3 #define M 10000005
     4 #define LL long long
     5 #define inf 0x3f3f3f3f
     6 using namespace std;
     7 inline int ra()
     8 {
     9     int x=0,f=1; char ch=getchar();
    10     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    11     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    12     return x*f;
    13 }
    14 struct node{
    15     int to,next;
    16 }e[N<<1];
    17 int head[N],cnt;
    18 int fa[N][20],deep[N],n,m;
    19 void insert(int x, int y){e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt;}
    20 void dfs(int x)
    21 {
    22     for (int i=1; i<=19; i++)
    23         if (deep[x]>=(1<<i))
    24             fa[x][i]=fa[fa[x][i-1]][i-1];
    25         else break;
    26     for (int i=head[x];i;i=e[i].next)
    27     {
    28         if (e[i].to==fa[x][0]) continue;
    29         fa[e[i].to][0]=x;
    30         deep[e[i].to]=deep[x]+1;
    31         dfs(e[i].to);
    32     }
    33 }
    34 int lca(int x, int y)
    35 {
    36     if (deep[x]<deep[y]) swap(x,y);
    37     int t=deep[x]-deep[y];
    38     for (int i=0; (1<<i)<=t ; i++)
    39         if (t&(1<<i)) x=fa[x][i];
    40     for (int i=19; i>=0; i--)
    41         if (fa[x][i]!=fa[y][i])
    42             x=fa[x][i],y=fa[y][i];
    43     if (x==y) return x;
    44     return fa[x][0];  
    45 }
    46 int lca_cost(int x, int y)
    47 {
    48     int sum=0;
    49     if (deep[x]<deep[y]) swap(x,y);
    50     int t=deep[x]-deep[y];
    51     for (int i=0; (1<<i)<=t ; i++)
    52         if (t&(1<<i)) x=fa[x][i],sum+=(1<<i);
    53     for (int i=19; i>=0; i--)
    54         if (fa[x][i]!=fa[y][i])
    55             x=fa[x][i],y=fa[y][i],sum+=(1<<i)*2;
    56     if (x==y) return sum;
    57     return sum+2;  
    58 }
    59 int main()
    60 {
    61     n=ra(); m=ra();
    62     for (int i=1; i<n; i++)
    63     {
    64         int x=ra(),y=ra();
    65         insert(x,y); insert(y,x);
    66     }
    67     dfs(1);
    68     for (int i=1; i<=m; i++)
    69     {
    70         int x=ra(),y=ra(),z=ra();
    71         int ans1=lca_cost(x,y)+lca_cost(lca(x,y),z);
    72         int ans2=lca_cost(x,z)+lca_cost(lca(x,z),y);
    73         int ans3=lca_cost(y,z)+lca_cost(lca(y,z),x);
    74         int ans=min(min(ans1,ans2),ans3);
    75         if (ans==ans1) printf("%d ",lca(x,y));
    76         else if (ans==ans2) printf("%d ",lca(x,z));
    77         else if (ans==ans3) printf("%d ",lca(y,z));
    78         printf("%d
    ",ans);
    79     }
    80 }
  • 相关阅读:
    leetcode 416. Partition Equal Subset Sum
    leetcode 696. Count Binary Substrings
    leetcode 74. Search a 2D Matrix
    leetcode 199. Binary Tree Right Side View
    leetcode 43. Multiply Strings
    leetcode 695. Max Area of Island
    leetcode 257. Binary Tree Paths
    leetcode 694. Number of Distinct Islands
    ros使用时的注意事项&技巧2
    ros使用时的注意事项&技巧
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6435291.html
Copyright © 2011-2022 走看看