• LOJ1036


    AHOI 2008 聚会

    Y 岛风景美丽宜人,气候温和,物产丰富。Y 岛上有 N 个城市,有 N-1 条城市间的道路连接着它们。每一条道路都连接某两个城市。幸运的是,小可可通过这些道路可以走遍 Y 岛的所有城市。神奇的是,乘车经过每条道路所需要的费用都是一样的。

    小可可,小卡卡和小 YY 经常想聚会,每次聚会,他们都会选择一个城市,使得三个人到达这个城市的总费用最小。

    由于他们计划中还会有很多次聚会,每次都选择一个地点是很烦人的事情,所以他们决定把这件事情交给你来完成。他们会提供给你地图以及若干次聚会前他们所处的位置,希望你为他们的每一次聚会选择一个合适的地点。

    输入格式

    第一行两个正整数,N 和 M。分别表示城市个数和聚会次数;

    后面有 N1 行,每行用两个正整数 A 和 B 表示编号为 A 和编号为 B 的城市之间有一条路。城市的编号是从 1 到 N 的;

    再后面有 M 行,每行用三个正整数表示一次聚会的情况:小可可所在的城市编号,小卡卡所在的城市编号以及小 YY 所在的城市编号。

    输出格式

    一共有 M 行,每行两个数 P 和 C,用一个空格隔开。表示第 ii 次聚会的地点选择在编号为 P 的城市,总共的费用是经过 C 条道路所花费的费用。

    样例

    样例输入

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

    样例输出

    5 2
    2 5
    4 1
    6 0

    数据范围与提示

    40% 的数据中,1N,M2×10^3;

    100% 的数据中,1N,M5×10^5。

    ________________________________________________________________________________________________

    题目还是很有意思的,但是调试时最后两个点超时,比较难调。主要是变成习惯不好!

    题目大意:树上有3个点,找一点,使得到3点的距离和最小。输出所找到的点和距离和。

    从图上看,3个点的关系有两种,一,第三点在前两点的路径上;二、第三点在前两点路径的某一点分出的岔路上;

    情况一,中间点就是聚会点,距离就是前两点的和;

    情况二, 那个“某一点”就是聚会点,距离为三点到“某一点”的距离。

    (证明可以贪心一下)

    那么最终结果就是,三点中两两求LCA,3个LCA求异或就是聚会点,而三个点到根的距离减去三个LCA到根的距离就是距离和。

    恶心的调试,最后两个点超时,都是1010ms

    改成优化读入,作用为0;

    把LCA中的循环从20开始改成log(dep[u])开始,第9个点变成了978ms,10号点没变。

    于是第一个循环改成

    while(dep[u]>dep[v])u=f[u][lg[dep[u]-dep[v]]];
    优化不大!!!

    最后把所有的LL变成的int,当然最终的距离除外!就OK了!!!
    而且时间大大优化!!!
    所以说,int还是比LL要快不少的。

    ________________________________________________________________________________________________

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const ll maxn=5e5+10;
     5 ll n,m;
     6 void readint(ll &x)
     7 {
     8     ll f=1;
     9     char c=getchar();
    10     for(;c>'9' || c<'0';c=getchar())if(c=='-')f=-f;
    11     x=0;
    12     for(;c>='0' && c<='9';c=getchar())x=x*10+c-'0';
    13     x*=f;
    14 }
    15 struct edge
    16 {
    17     ll u,v,nxt;
    18 }e[maxn<<1];
    19 ll head[maxn],js;
    20 ll lg[maxn];
    21 void init()
    22 {
    23     lg[0]=-1;
    24     for(int i=1;i<n;++i)lg[i]=lg[i>>1]+1;
    25 }
    26 void addage(ll u,ll v)
    27 {
    28     e[++js].u=u;e[js].v=v;
    29     e[js].nxt=head[u];head[u]=js;
    30 }
    31 ll f[maxn][20],dep[maxn];
    32 void dfs(ll u,ll fa)
    33 {
    34     f[u][0]=fa;dep[u]=dep[fa]+1;
    35     for(ll i=1;(1<<i)<dep[u];++i)f[u][i]=f[f[u][i-1]][i-1];
    36     for(ll i=head[u];i;i=e[i].nxt)
    37     {
    38         ll v=e[i].v;
    39         if(v!=fa)dfs(v,u);
    40     }
    41 }
    42 ll lca(ll u,ll v)
    43 {
    44     if(dep[u]<dep[v])swap(u,v);
    45     while(dep[u]>dep[v])u=f[u][lg[dep[u]-dep[v]]];
    46     if(u==v)return u;
    47     for(ll i=lg[dep[u]];i>=0;--i)if(f[u][i]!=f[v][i])u=f[u][i],v=f[v][i];
    48     return f[u][0];
    49 }
    50 int main()
    51 {
    52     readint(n);readint(m);
    53     for(ll u,v,i=1;i<n;++i)
    54     {
    55         readint(u);readint(v);
    56         addage(u,v);addage(v,u);
    57     }
    58     dfs(1,0);
    59     init();
    60     while(m--)
    61     {
    62         ll a,b,c,l1,l2,l3;
    63         readint(a);readint(b);readint(c);
    64         l1=lca(a,b);l2=lca(b,c);l3=lca(c,a);
    65         printf("%lld %lld
    ",l1^l2^l3,dep[a]+dep[b]+dep[c]-dep[l1]-dep[l2]-dep[l3]);
    66     }
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    Pig与Hive的区别
    Hadoop MapReduceV2(Yarn) 框架简介
    Spark技术内幕:Client,Master和Worker 通信源码解析
    Spark技术内幕:Stage划分及提交源码分析
    无责任比较thrift vs protocol buffers
    理解hadoop的Map-Reduce数据流(data flow)
    hadoop-2.5安装与配置
    linux下查看本地程序占用的端口
    MFC安装与部署(程序打包)
    关系数据库设计中数据字典设计例子
  • 原文地址:https://www.cnblogs.com/gryzy/p/10406932.html
Copyright © 2020-2023  润新知