zoukankan      html  css  js  c++  java
  • cogs 186. [USACO Oct08] 牧场旅行 树链剖分 LCA

    186. [USACO Oct08] 牧场旅行

    ★★☆   输入文件:pwalk.in   输出文件:pwalk.out   逐字节对比
    时间限制:1 s   内存限制:128 MB

    n个被自然地编号为1..n奶牛(1<=n<=1000)正在同样被方便的编号为1..n的n个牧场中吃草。更加自然而方便的是,第i个奶牛就在第i个牧场中吃草。

    其中的一些对牧场被总共的n-1条双向通道的一条连接。奶牛可以通过通道。第i条通道连接的两个牧场是A_i和B_i(1<=A_i<=N;1<=B_i<=N)其长度是L_i(1<=L_i<=10000)。

    通道只会连接两个不同的牧场,所以这些通道使得整个牧场构成了一棵树。

    奶牛们是好交际的希望能够经常的访问别的奶牛。急切地,它们希望你能通过告诉它们Q(1<=Q<=1000)对牧场的路径来帮助他们安排旅行。(这里将有Q个询问,p1,p2(1<=p1<=n;1<=p1<=n))

    分数:200

    问题名称:pwalk

    输入格式:

    • 第1行:两个用空格隔开的整数:n和Q
    • 第2..n行:第i+1行包含三个用空格隔开的整数:A_i,B_i和L_i
    • 第n+1..N+Q行:每行包含两个用空格隔开的整数,代表两个不同的牧场,p1和p2

    输入样例(file pwalk.in):

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

    输出格式:

    • 第1..Q行:行i包含第i个询问的答案。

    输出样例:

    2
    7
    

    输出说明:

    询问1:牧场1和牧场2的路径长度为2。 询问2:3->4->1->2;总长为7。

    就是一个树链剖分求LCA

    #include<bits/stdc++.h>
    #define maxn 1005
    using namespace std;
    int N,Q;
    vector<int> v[maxn],w[maxn];
    int dis[maxn];
    int size[maxn],dep[maxn],fa[maxn],son[maxn],pos[maxn],dfn[maxn];
    int cnt,top[maxn];
    void Dfs(int x)
    {
        size[x]=1; 
        for(int i=0;i<v[x].size();i++)
        {
            int y=v[x][i];
            if(!size[y])
            {
                fa[y]=x;
                dep[y]=dep[x]+1;
                   dis[y]=dis[x]+w[x][i];
                Dfs(y);
                size[x]+=size[y];
                if(size[y]>size[son[x]])
                    son[x]=y;//更新重儿子 
            }
        }
    }
    void Dfs(int x,int Tp)
    {
        top[x]=Tp;
        dfn[++cnt]=x;
        pos[x]=cnt;
        if(son[x])
        {
            Dfs(son[x],Tp);//先走重链 
        }
        for(int i=0;i<v[x].size();i++)
        {
            int to=v[x][i];
            if(!top[to])
            {
                Dfs(to,to);//轻链 
            }
        }
    }
    int LCA(int x,int y)
    {
        while(top[x]!=top[y])
        {
            if(dep[top[x]]<dep[top[y]])
                swap(x,y);
            x=fa[top[x]];
        }
        if(dep[x]>dep[y])
            swap(x,y);
        return x;
    }
    int main()
    {
    //    freopen("pwalk.in","r",stdin);
    //    freopen("pwalk.out","w",stdout);
        scanf("%d%d",&N,&Q);
        for(int i=2;i<=N;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            v[x].push_back(y);
            w[x].push_back(z);
            v[y].push_back(x);
            w[y].push_back(z);
        }
        Dfs(1);Dfs(1,1);
        for(int i=1;i<=Q;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            printf("%d
    ",dis[x]+dis[y]-2*dis[LCA(x,y)]);
        }
    
    
        return 0;
    }
  • 相关阅读:
    蛙蛙推荐:JS里声明事件处理的几种方式
    蛙蛙推荐:asp错误处理
    蛙蛙推荐:偶心目中的编程高手,大家也推荐一下
    access能否用vbs来写存储过程,是否支持参数名称 【星期一 2005年7月4日】
    MySQL索引相关
    ubuntu 禁用触摸板
    ubuntuFQ(转)
    bash编程笔记
    Hive环境搭建与入门(转)
    Linux SSH远程文件/目录传输命令scp
  • 原文地址:https://www.cnblogs.com/Tidoblogs/p/11344732.html
Copyright © 2011-2022 走看看