• BZOJ 1787: [Ahoi2008]Meet 紧急集合


    Description

    Sample Input

    6 4
    1 2
    2 3
    2 4
    4 5
    5 6
    4 5 6
    6 3 1
    2 4 4
    6 6 6

    Sample Output

    5 2
    2 5
    4 1
    6 0

    思路:唔,直接暴力求出三个lca判断一下哪个lca是题目所要求的点就好了

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<queue>
     5 #define maxn 1000009
     6 #define D 20
     7 using namespace std;
     8 int head[maxn],nex[maxn],point[maxn];
     9 int fa[maxn][D+10],x,y,z,now,deep[maxn];
    10 void add(int x,int y)
    11 {
    12     nex[++now] = head[x];
    13     head[x] = now;
    14     point[now] = y;
    15 }
    16 void bfs(int s)
    17 {
    18     queue<int>q;
    19     q.push(s);
    20     while(!q.empty())
    21     {
    22         int u = q.front();
    23         //printf("%d
    ",u);
    24         q.pop();
    25         for(int i = head[u]; i; i=nex[i])
    26         {
    27             int k = point[i];
    28             if(k == fa[u][0])continue;
    29             q.push(k);
    30             fa[k][0] = u;
    31             for(int j = 1; j < D; j++)fa[k][j] = fa[fa[k][j-1]][j-1];
    32             deep[k] = deep[u] + 1;
    33         }
    34     }
    35 }
    36 int lca(int x,int y)
    37 {
    38     if(deep[x]>deep[y])swap(x,y);
    39     int tx = x, ty = y,delta = deep[y] - deep[x];
    40     for(int i = 0;delta;delta>>=1,i++)if(delta&1)
    41     {
    42         ty = fa[ty][i];
    43     }
    44     if(tx == ty)return tx;
    45     for(int i = D; i>=0;i--)
    46     {
    47         if(fa[tx][i] == fa[ty][i])continue;
    48         tx = fa[tx][i];
    49         ty = fa[ty][i];
    50     }
    51     return fa[tx][0];
    52 }
    53  
    54 int main()
    55 {
    56     int n,m;
    57     scanf("%d%d",&n,&m);
    58     for(int i=1;i<n;i++)
    59     {
    60         scanf("%d%d",&x,&y);
    61         add(x,y);
    62         add(y,x);
    63     }
    64     //puts("0");
    65     bfs(1);
    66     //puts("1");
    67     for(int i = 1; i <= m; i++)
    68     {
    69         scanf("%d%d%d",&x,&y,&z);
    70         int a = lca(x,y),b=lca(x,z),c= lca(y,z);
    71         int ans = (deep[x]+deep[y]-deep[a])+deep[z]-2*deep[lca(a,z)],ansj = a;
    72         int u;
    73         if((u = (deep[x]+deep[z]-deep[b]+deep[y]-2*deep[lca(b,y)]))<ans)
    74         {
    75             ans = u;
    76             ansj = b;
    77         }
    78         if((u = (deep[y]+deep[z]-deep[c]+deep[x]-2*deep[lca(c,x)]))<ans)
    79         {
    80             ans = u;
    81             ansj = c;
    82         }
    83         printf("%d %d
    ",ansj,ans);
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    Floyd_Warshall算法
    Bellman_Ford算法
    深度优先搜索
    广度优先搜索
    贪心算法_活动选择
    动态规划_0-1背包问题
    算法导论_动态规划_最长回文子序列
    算法导论_动态规划_最长公共子序列
    动态规划解决分割问题
    2016 Google中国开发者大会游记
  • 原文地址:https://www.cnblogs.com/philippica/p/4796297.html
Copyright © 2020-2023  润新知