【9018:1893】牧场行走

问题 C: 牧场行走

时间限制: 1 Sec  内存限制: 128 MB
提交: 74  解决:
36
[提交][状态][讨论版]

题目描述

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

输入

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

第二行到第n行:第i+1行有两个被空格隔开的整数:Ai,Bi,Li

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

输出

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

样例输入

5 3
2 1 1
3 2 2
4 1 4
5 2 8
3 4
3 5
4 5

样例输出

7
10
13

提示

2<=n,q<=1000

题解:树上倍增lca,求树上两节点a、b的距离即为dis[a]+dis[b]-2*dis[lca(a,b)](其中dis表示该节点到根的距离)。

代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #define maxpow 10
 5 using namespace std;
 6 int n,p,fa[12][1005],dep[1005],dis[1005];
 7 int cnt,head[1005];
 8 bool vis[1005];
 9 struct edge{int to,next,val;}e[2005];
10 void ins(int x,int y,int v){e[++cnt].to=y;e[cnt].next=head[x];head[x]=cnt;e[cnt].val=v;}
11 void dfs(int u){
12     vis[u]=true;
13     for(int i=1;i<maxpow;i++)
14         if(dep[u]<(1<<i)) break;
15         else fa[i][u]=fa[i-1][fa[i-1][u]];//倍增操作
16     for(int i=head[u];i;i=e[i].next){
17         int v=e[i].to;
18         if(vis[v]) continue;
19         dep[v]=dep[u]+1; dis[v]=dis[u]+e[i].val;
20         fa[0][v]=u; dfs(v);
21     }
22 }
23 int lca(int u,int v){
24     if(dep[u]<dep[v]) swap(u,v);
25     int dif=dep[u]-dep[v];
26     for(int i=0;i<maxpow;i++) if((1<<i)&dif) u=fa[i][u];//u向上移动至于v同一深度
27     if(u==v) return u;
28     for(int i=maxpow-1;i>=0;i--)
29         if(fa[i][u]!=fa[i][v]){u=fa[i][u]; v=fa[i][v];}//u、v同时倍增
30     return fa[0][u];//注意这里返回fa
31 }
32 int main()
33 {
34     scanf("%d%d",&n,&p);
35     for(int i=1;i<n;i++){
36         int x,y,l;
37         scanf("%d%d%d",&x,&y,&l);
38         ins(x,y,l); ins(y,x,l);
39     }
40     dfs(1);
41     for(int i=1;i<=p;i++){
42         int x,y; scanf("%d%d",&x,&y);
43         printf("%d\n",dis[x]+dis[y]-2*dis[lca(x,y)]);
44     }
45     return 0;
46 }
时间: 2024-10-07 12:40:48

【9018:1893】牧场行走的相关文章

[BZOJ1602][Usaco2008 Oct]牧场行走

1602: [Usaco2008 Oct]牧场行走 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 2065  Solved: 1084[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<

树讲解——牧场行走( lca )

大视野   1602: [Usaco2008 Oct]牧场行走 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1947  Solved: 1021[Submit][Status][Discuss] Description N头牛(2<=n<=1000)别人被标记为1到n,在同样被标记1到n的n块土地上吃草,第i头牛在第i块牧场吃草. 这n块土地被n-1条边连接. 奶牛可以在边上行走,第i条边连接第Ai,Bi块牧场,第i条边的长度是Li(1<=

【bzoj1602】[Usaco2008 Oct]牧场行走

1602: [Usaco2008 Oct]牧场行走 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 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<=

1602: [Usaco2008 Oct]牧场行走

1602: [Usaco2008 Oct]牧场行走 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 1211  Solved: 616 [Submit][Status] Description N头牛(2<=n<=1000)别人被标记为1到n,在同样被标记1到n的n块土地上吃草,第i头牛在第i块牧场吃草. 这n块土地被n-1条边连接. 奶牛可以在边上行走,第i条边连接第Ai,Bi块牧场,第i条边的长度是Li(1<=Li<=10000).

bzoj 1602 [Usaco2008 Oct]牧场行走(LCA模板)

1602: [Usaco2008 Oct]牧场行走 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 379  Solved: 216[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<=1

[bzoj] 1602 牧场行走

1602: [Usaco2008 Oct]牧场行走 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 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). 这些边被安排成任意两头奶牛都可以

[Usaco2008 Oct][BZOJ1602] 牧场行走

1602: [Usaco2008 Oct]牧场行走 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 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<=

BZOJ 1602: [Usaco2008 Oct]牧场行走( 最短路 )

一棵树..或许用LCA比较好吧...但是我懒...写了个dijkstra也过了.. ---------------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<queue> #include<cstring> #include<iostream> #define rep( i ,

[BZOJ1602] [Usaco2008 Oct] 牧场行走 (LCA)

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 *