• 【bzoj1602】[Usaco2008 Oct]牧场行走


    1602: [Usaco2008 Oct]牧场行走

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 1793  Solved: 935
    [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
     
     
    【题解】
    dis(x,y)=dis(x,1)+dis(y,1)-2*dis( lca(x,y) , 1)
    很水的题。。。
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<ctime>
     7 #include<algorithm>
     8 using namespace std;
     9 #define MAXN 1010
    10 struct node{int y,next,v;}e[MAXN*2];
    11 int n,m,len,Link[MAXN],f[MAXN],deep[MAXN],dis[MAXN],anc[MAXN][25];
    12 inline int read()
    13 {
    14     int x=0,f=1;  char ch=getchar();
    15     while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getchar();}
    16     while(isdigit(ch))  {x=x*10+ch-'0';  ch=getchar();}
    17     return x*f;
    18 }
    19 void insert(int x,int y,int v)  {e[++len].next=Link[x];Link[x]=len;e[len].y=y;e[len].v=v;}
    20 void dfs(int x,int fa)
    21 {
    22     anc[x][0]=f[x];
    23     for(int i=1;i<=20;i++)  anc[x][i]=anc[anc[x][i-1]][i-1];
    24     for(int i=Link[x];i;i=e[i].next)
    25         if(e[i].y!=fa)
    26         {
    27             deep[e[i].y]=deep[x]+1;
    28             dis[e[i].y]=dis[x]+e[i].v;
    29             f[e[i].y]=x;
    30             dfs(e[i].y,x);
    31         }
    32 }
    33 int lca(int x,int y)
    34 {
    35     if(deep[x]<deep[y])  swap(x,y);
    36     for(int i=20;i>=0;i--)
    37         if(deep[anc[x][i]]>=deep[y])  x=anc[x][i];
    38     if(x==y)  return x;
    39     for(int i=20;i>=0;i--)
    40         if(anc[x][i]!=anc[y][i])  x=anc[x][i],y=anc[y][i];
    41     return f[x];
    42 }
    43 int main()
    44 {
    45     //freopen("cin.in","r",stdin);
    46     //freopen("cout.out","w",stdout);
    47     n=read();  m=read();
    48     for(int i=1;i<n;i++)  {int x=read(),y=read(),v=read();  insert(x,y,v);  insert(y,x,v);}
    49     deep[1]=1;  dfs(1,0);
    50     for(int i=1;i<=m;i++)
    51     {
    52         int x=read(),y=read();
    53         printf("%d
    ",dis[x]+dis[y]-2*dis[lca(x,y)]);
    54     }
    55     return 0;
    56 }
  • 相关阅读:
    Jenkins 基础篇
    Jenkins 基础篇
    Windows配置Nodejs环境
    Windows配置安装JDK
    Windows安装MySQL
    Ubuntu安装MySQL
    利用中国移动合彩云实现360云盘迁移到百度云
    Linux Shell下的后台运行及其前台的转换
    nova image-list 和 glance image-list 有什么区别
    启动虚拟机时提示我已移动或我已复制选项的详解
  • 原文地址:https://www.cnblogs.com/chty/p/5971457.html
Copyright © 2020-2023  润新知