• 【BZOJ】1832: [AHOI2008]聚会


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1832


    省选出出了CF的感觉.....

    显然一发贪心,如果两个点显然就是他们的$LCA$(不在一条链上的情况),第三个点不就直接走到这个$LCA$么,考虑$3$种分别组合的情况即可。


     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<vector>
     5 #include<cstdlib>
     6 #include<cmath>
     7 #include<cstring>
     8 using namespace std;
     9 #define maxn 500100
    10 #define llg int
    11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    12 llg n,m,f[maxn][21],deep[maxn];
    13 vector<llg>a[maxn];
    14 
    15 void dfs(llg x,llg fa)
    16 {
    17     llg w=a[x].size(),v;
    18     deep[x]=deep[fa]+1,f[x][0]=fa;
    19     for (llg i=0;i<w;i++)
    20     {
    21         v=a[x][i];
    22         if (v==fa) continue;
    23         dfs(v,x);
    24     }
    25 }
    26 
    27 void make_f()
    28 {
    29     for (llg j=1;j<=20;j++)
    30         for (llg i=1;i<=n;i++)
    31             f[i][j]=f[f[i][j-1]][j-1];
    32 }
    33 
    34 llg find(llg x,llg y)
    35 {
    36     if (deep[x]<deep[y]) swap(x,y);
    37     for (llg i=20;i>=0;i--)
    38         if (deep[f[x][i]]>=deep[y])
    39             x=f[x][i];
    40     if (x==y) return x;
    41     for (llg i=20;i>=0;i--)
    42         if (f[x][i]!=f[y][i])
    43             x=f[x][i],y=f[y][i];
    44     return f[x][0];
    45 }
    46 
    47 void init()
    48 {
    49     llg x,y;
    50     cin>>n>>m;
    51     for (llg i=1;i<n;i++)
    52     {
    53         scanf("%d%d",&x,&y);
    54         a[x].push_back(y),a[y].push_back(x);
    55     }
    56     dfs(1,0);
    57     make_f();
    58 }
    59 
    60 llg dis(llg x,llg y){return deep[x]+deep[y]-deep[find(x,y)]*2;}
    61 
    62 int main()
    63 {
    64     yyj("bzoj1832");
    65     init();
    66     llg x,y,z,val,po,ans;
    67     while (m--)
    68     {
    69         ans=0x7fffffff;
    70         scanf("%d%d%d",&x,&y,&z);
    71 
    72         val=dis(x,y)+dis(find(x,y),z);
    73         if (val<ans) {ans=val,po=find(x,y);}
    74 
    75         val=dis(z,y)+dis(find(z,y),x);
    76         if (val<ans) {ans=val,po=find(z,y);}
    77 
    78         val=dis(x,z)+dis(find(x,z),y);
    79         if (val<ans) {ans=val,po=find(x,z);}
    80 
    81         printf("%d %d
    ",po,ans);
    82     }
    83     return 0;
    84 }
  • 相关阅读:
    回文字符串系列问题
    找两个数组的重合数字系列
    IPC最快的方式----共享内存(shared memory)
    【经典算法】——KMP,深入讲解next数组的求解
    关于SqlDateTime溢出的问题
    git操作之常见问题解决方案
    Javascript中length属性的总结
    从零开始学node(一): nodejs开发环境的配置
    使用Number.parseFloat引发的悲剧
    超链接的那些事(三): 属性target
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/6517940.html
Copyright © 2020-2023  润新知