• [Usaco2008 Oct][BZOJ1602] 牧场行走


    1602: [Usaco2008 Oct]牧场行走

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 1382  Solved: 696
    [Submit][Status][Discuss]

    Description

    N头牛(2<=n<=1000)别人被标记为1到n,在同样被标记1到n的n块土地上吃草,第i头牛在第i块牧场吃草。 这n块土地被n-1条边连接。 奶牛可以在边上行走,第i条边连接第Ai,Bi块牧场,第i条边的长度是Li(1<=Li<=10000)。 这些边被安排成任意两头奶牛都可以通过这些边到达的情况,所以说这是一棵树。 这些奶牛是非常喜欢交际的,经常会去互相访问,他们想让你去帮助他们计算Q(1<=q<=1000)对奶牛之间的距离。

    Input

    *第一行:两个被空格隔开的整数:N和Q

     *第二行到第n行:第i+1行有两个被空格隔开的整数:AI,BI,LI

    *第n+1行到n+Q行:每一行有两个空格隔开的整数:P1,P2,表示两头奶牛的编号。

    Output

    *第1行到第Q行:每行输出一个数,表示那两头奶牛之间的距离。

    Sample Input

    4 2
    2 1 2
    4 3 2
    1 4 3
    1 2
    3 2

    Sample Output

    2
    7

    HINT

     

    Source

     
    倍增求LCA,维护该点到根节点的路径长度。
     
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<vector>
    #include<set>
    #include<map>
    #include<queue>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int n,q,x,y,z,p1,p2,tot,head[1001],list[2002],next[2002],key[2002],sum[1001],deep[1001],f[1001][20];
    void insert(int x,int y,int z)
    {
        next[++tot]=head[x];
        head[x]=tot;
        list[tot]=y;
        key[tot]=z;
    }
    void dfs(int u)
    {
        for (int i=1;i<=14;i++)
        {
            if (deep[u]<(1<<i)) break;
            f[u][i]=f[f[u][i-1]][i-1];
        }
        for (int v=head[u];v;v=next[v])
            if (!deep[list[v]])
            {
                sum[list[v]]=sum[u]+key[v];
                deep[list[v]]=deep[u]+1;
                f[list[v]][0]=u;
                dfs(list[v]);
            }    
    }
    int lca(int a,int b)
    {
        if (deep[a]<deep[b]) swap(a,b);
        int t=deep[a]-deep[b]; 
        for (int i=0;i<=14;i++)
            if ((t&(1<<i))) a=f[a][i];
        for (int i=14;i>=0;i--)
            if (f[a][i]!=f[b][i])
            {
                a=f[a][i];
                b=f[b][i];
            }
        if (a==b) return a; else return f[a][0];
    }
    int main()
    {
        scanf("%d%d",&n,&q);
        for (int i=1;i<n;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            insert(x,y,z);
            insert(y,x,z);
        }
        deep[1]=1;
        dfs(1);
        for (int i=1;i<=q;i++)
        {
            scanf("%d%d",&p1,&p2);
            int x=lca(p1,p2);
            printf("%d
    ",sum[p1]+sum[p2]-2*sum[x]);
        }
        return 0;
    }
  • 相关阅读:
    真正明白了引用与对象的关系,就能避开下面这个陷阱
    python 垃圾回收
    字典
    表的操作
    MySQL数据库中的存储引擎
    MySQL数据库的基本操作
    MySQL数据库安装文件夹与配置文件简易说明
    数据库概述
    Arrays类
    Math类
  • 原文地址:https://www.cnblogs.com/ws-fqk/p/4655091.html
Copyright © 2020-2023  润新知