【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\n",dis[x]+dis[y]-2*dis[lca(x,y)]);
54     }
55     return 0;
56 }

 

posted @ 2016-10-17 22:07  chty  阅读(161)  评论(0编辑  收藏  举报