• [bzoj] 1602 牧场行走


    1602: [Usaco2008 Oct]牧场行走

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 2013  Solved: 1059

    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

    Source

    资格赛

    Analysis

    树上求两点间距离,倍增求LCA顺带维护倍增距离即可。

    Code

     1 #include<cstdio>
     2 #include<iostream>
     3 #define maxn 20005
     4 using namespace std;
     5 
     6 struct edge{
     7     int from,v,len;
     8 }e[maxn];
     9 
    10 int tot,first[maxn],n,q,a,b,c;
    11 void insert(int u,int v,int len){
    12     tot++;
    13     e[tot].from = first[u];
    14     e[tot].v = v;
    15     e[tot].len = len;
    16     first[u] = tot;
    17 }
    18 
    19 bool book[maxn]; int depth[maxn],fa[maxn][20],cost[maxn][20];
    20 void dfs(int now){
    21     for(int i = first[now];i;i = e[i].from){
    22         int v = e[i].v;
    23         if(!book[v]){
    24             book[v] = true;
    25             depth[v] = depth[now]+1;
    26             fa[v][0] = now;
    27             cost[v][0] = e[i].len;
    28             for(int i = 1;i <= 18;i++)
    29                 fa[v][i] = fa[fa[v][i-1]][i-1],
    30                 cost[v][i] = cost[fa[v][i-1]][i-1]+cost[v][i-1];
    31             dfs(v);
    32         }
    33     }
    34 }
    35 
    36 int LCA(int u,int v){
    37     int ans = 0;
    38     if(depth[u] < depth[v]) swap(u,v);
    39     for(int i = 18;i >= 0;i--)
    40         if(depth[fa[u][i]] >= depth[v])
    41             ans += cost[u][i],u = fa[u][i];
    42     if(u == v) return ans;
    43     for(int i = 18;i >= 0;i--)
    44         if(fa[u][i] != fa[v][i])
    45             ans += cost[u][i]+cost[v][i],
    46             u = fa[u][i],v = fa[v][i];
    47     return ans+cost[u][0]+cost[v][0];
    48 }
    49 
    50 int main(){
    51     scanf("%d%d",&n,&q);
    52     
    53     for(int i = 1;i < n;i++){
    54         scanf("%d%d%d",&a,&b,&c);
    55         insert(a,b,c);
    56         insert(b,a,c);
    57     }
    58     
    59     book[1] = true;
    60     depth[1] = 1;
    61     dfs(1);
    62     
    63 //    for(int i = 0;i <= n;i++){
    64 //        for(int j = 0;j <= 18;j++){
    65 //            printf("%d ",fa[i][j]);
    66 //        }cout << endl;
    67 //    }
    68     
    69     for(int i = 0;i < q;i++){
    70         scanf("%d%d",&a,&b);
    71         printf("%d
    ",LCA(a,b));
    72     }
    73     
    74     return 0;
    75 }
    这么水的题居然还权限= =
    转载请注明出处 -- 如有意见欢迎评论
  • 相关阅读:
    振动传感器
    水银开关式碰撞传感器
    倾斜传感器
    光敏传感器
    激光传感器的使用
    html字符串 转 json
    浏览器播放视频加快进功能
    处理箭头函数单个参数括号规则冲突
    VUE-directive指令之语法、引用、钩子函数、参数
    win10系统自动升级怎么还原到以前的系统
  • 原文地址:https://www.cnblogs.com/Chorolop/p/7353660.html
Copyright © 2020-2023  润新知