zoukankan      html  css  js  c++  java
  • BZOJ1832 聚会

    Description:
    Y岛风景美丽宜人,气候温和,物产丰富。Y岛上有N个城市,有N-1条城市间的道路连接着它们。每一条道路都连接某两个城市。幸运的
    是,小可可通过这些道路可以走遍Y岛的所有城市。神奇的是,乘车经过每条道路所需要的费用都是一样的。小可可,小卡卡和小YY经常
    想聚会,每次聚会,他们都会选择一个城市,使得3个人到达这个城市的总费用最小。 由于他们计划中还会有很多次聚会,每次都选择一
    个地点是很烦人的事情,所以他们决定把这件事情交给你来完成。他们会提供给你地图以及若干次聚会前他们所处的位置,希望你为他们
    的每一次聚会选择一个合适的地点。
    Input:
    第一行两个正整数,NM。分别表示城市个数和聚会次数。后面有N-1行,每行用两个正整数AB表示编号为A和编号为B的城市之间有
    一条路。城市的编号是从1N的。再后面有M行,每行用三个正整数表示一次聚会的情况:小可可所在的城市编号,小卡卡所在的城市
    编号以及小YY所在的城市编号。
    Output:
    一共有M行,每行两个数PosCost,用一个空格隔开。表示第i次聚会的地点选择在编号为Pos的城市,总共的费用是经过Cost条道路所
    花费的费用。

    思路:思路很一眼,就是对每一组输入,有三种情况,A走到B和C的LCA出,B走到A和C的LCA处,C走到A和B的LCA处,不过细节小心,不要写挂

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 5e5 + 10;
     
    int head[N], now;
    struct edges{
        int to, next;
    }edge[N<<1];
    void add(int u,int v){ edge[++now] = {v, head[u]}; head[u] = now;}
     
    int n, m, fa[N][22], dep[N];
    void dfs(int x, int pre){
        fa[x][0] = pre;
        for(int i = head[x]; i; i = edge[i].next){
            int v = edge[i].to;
            if(v == pre) continue;
            dep[v] = dep[x] + 1;
            dfs(v, x);
        }
    }
    int LCA(int u,int v){
        if(dep[v] > dep[u]) swap(u, v);
        int k=dep[u]-dep[v];
        for(int i=0;i<=20;i++)
          if((1<<i)&k) u=fa[u][i];
        if(u == v) return u;
        for(int i = 20; i >= 0; i--)
          if(fa[u][i] != fa[v][i]) 
            u = fa[u][i], v = fa[v][i];
        return fa[u][0];
         
    }
    int main(){
        scanf("%d%d",&n, &m);
        int x, y, z;
        for(int i = 1; i < n; i++){
            scanf("%d%d",&x, &y);
            add(x, y); add(y, x);
        }
        dep[1] = 1; dfs(1, 1);  
        for(int j = 0; j <= 20; j++)
          for(int i = 1; i <= n; i++)
            fa[i][j + 1] = fa[fa[i][j]][j];
        for(int i = 1; i <= m; i++){
            scanf("%d%d%d",&x, &y, &z);
            int lca, pos, tmp, tot = 0, ans = 1e9;
             
            lca = LCA(x, y); tot += dep[x] + dep[y] - 2*dep[lca];
            tmp = LCA(lca, z); tot += dep[z] + dep[lca] - 2*dep[tmp];
            if(tot < ans) ans = tot, pos = lca;
             
            swap(x, z); tot = 0; 
            lca = LCA(x, y); tot += dep[x] + dep[y] - 2*dep[lca];
            tmp = LCA(lca, z); tot += dep[z] + dep[lca] - 2*dep[tmp];
            if(tot < ans) ans = tot, pos = lca;
             
            swap(y, z); tot = 0; 
            lca = LCA(x, y); tot += dep[x] + dep[y] - 2*dep[lca];
            tmp = LCA(lca, z); tot += dep[z] + dep[lca] - 2*dep[tmp];
            if(tot < ans) ans = tot, pos = lca;
             
            printf("%d %d
    ", pos, ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    1012 The Best Rank (25 分)(排序)
    1011. World Cup Betting (20)(查找元素)
    1009 Product of Polynomials (25 分)(模拟)
    1008 Elevator (20 分)(数学问题)
    1006 Sign In and Sign Out (25 分)(查找元素)
    1005 Spell It Right (20 分)(字符串处理)
    Kafka Connect 出现ERROR Failed to flush WorkerSourceTask{id=local-file-source-0}, timed out while wait
    flume、kafka、avro组成的消息系统
    Java23种设计模式总结【转载】
    Java编程 思维导图
  • 原文地址:https://www.cnblogs.com/Rorshach/p/8724875.html
Copyright © 2011-2022 走看看