zoukankan      html  css  js  c++  java
  • 1558:聚会 ybt

    1558:聚会 ybt 题解(看似很难,其实要是摸清了实质这就是个大水题)

    上题目

    1558:聚会


    时间限制: 1000 ms         内存限制: 524288 KB
    提交数: 82     通过数: 56

    【题目描述】

    原题来自:AHOI 2008

    Y

    岛风景美丽宜人,气候温和,物产丰富。Y 岛上有 N 个城市,有 N1 条城市间的道路连接着它们。每一条道路都连接某两个城市。幸运的是,小可可通过这些道路可以走遍 Y

    岛的所有城市。神奇的是,乘车经过每条道路所需要的费用都是一样的。

    小可可,小卡卡和小 YY

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

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

    【输入】

    第一行两个正整数,N

    M

    。分别表示城市个数和聚会次数;

    后面有 N1

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

    的;

    再后面有 M

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

    所在的城市编号。

    【输出】

    一共有 M

    行,每行两个数 PC,用一个空格隔开。表示第 i 次聚会的地点选择在编号为 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×103

    100% 的数据中,1N,M5×105

    乍一看这道题正常人的脑子里都会想到最短路 在不看这一节的标题的情况下

    但是这道题的本质却是找规律。。。。在纸上画一画就很容易想到

    我们分别找出这三个点的LCA,会发现三个LCA当中必有两个相同的点(可以数学证明但是我不会)

    而最终要去的那个点就是除了上述两点之外的第三个点

    #include<bits/stdc++.h>
    using namespace std;
    const int N=5e5+1;
    int n,m,tot;
    int next[N<<1],head[N<<1],f[N<<1][21],Dep[N<<1],to[N<<1];
    
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-') f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    
    inline void Add(int from,int pos)
    {
        next[++tot]=head[from];
        head[from]=tot;
        to[tot]=pos;
    }
    
    inline void Pre(int u,int fa)
    {
        Dep[u]=Dep[fa]+1;
        f[u][0]=fa;
        for(int i=1;i<=19;i++)
        f[u][i]=f[f[u][i-1]][i-1];
        for(int i=head[u];i;i=next[i])
        {
            if(to[i]==fa) continue;
            //dis[to[i]]=dis[u]+1;
            Pre(to[i],u);
        }
    }
    
    inline int LCA(int x,int y)
    {
        if(Dep[x]<Dep[y]) swap(x,y);
        for(int i=19;i>=0;i--)
        {
            if(Dep[f[x][i]]>=Dep[y]) x=f[x][i];
            if(x==y) return x;
        }
        for(int i=19;i>=0;i--)
        {
            if(f[x][i]!=f[y][i])
            {
                x=f[x][i];
                y=f[y][i];
            }
        }
        return f[x][0];
    }
    
    inline int Q(int x,int y)
    {
        return (Dep[x]+Dep[y]-2*Dep[LCA(x,y)]);
    }
    
    inline int query(int x,int y,int z,int end)
    {
        return (Q(x,end)+Q(y,end)+Q(z,end));
    }
    int main()
    {
        n=read();m=read();
        int x,y,z;
        int A,B,C; 
        for(int i=1;i<n;i++)
        {
            x=read();y=read();
            Add(x,y);
            Add(y,x);
        }
        Pre(1,1);
        for(int i=1;i<=m;i++)
        {
            x=read();y=read();z=read();
            A=LCA(x,y);
            B=LCA(x,z);
            C=LCA(y,z);
            if(A==B) printf("%d %d
    ",C,query(x,y,z,C));
            else if(A==C) printf("%d %d
    ",B,query(x,y,z,B));
            else printf("%d %d
    ",A,query(x,y,z,A));
        }
        return 0;
    }
    喵内喵内
  • 相关阅读:
    VIJOS-P1340 拯救ice-cream(广搜+优先级队列)
    uva 11754 Code Feat
    uva11426 GCD Extreme(II)
    uvalive 4119 Always an Interger
    POJ 1442 Black Box 优先队列
    2014上海网络赛 HDU 5053 the Sum of Cube
    uvalive 4795 Paperweight
    uvalive 4589 Asteroids
    uvalive 4973 Ardenia
    DP——数字游戏
  • 原文地址:https://www.cnblogs.com/smartljy/p/11352845.html
Copyright © 2011-2022 走看看