题目描述

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))

输入格式

第1行:两个用空格隔开的整数:n和Q

第2..n行:第i+1行包含三个用空格隔开的整数:A_i,B_i和L_i

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

输出格式

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


很基础的LCA题。

本题的重点就是计算树上距离。树上距离怎么算?我们可以在线算,也可以离线算。

首先明确思路,dist(u,v)=dist(u,lca(u,v))+dist(lca(u,v),v)。然后我们讨论两种做法:

在线。借助于倍增的做法,用dis(i,j)表示i往上走2^j步走过的距离。那么可以得出以下的递推公式——

\[dis[i][j]=dis[i][j-1]+dis[fa[i][j-1]][j-1]
\]

初始化dis(i,0)为i与父亲之间边的边长。其中fa(i,j)表示i往上走2^j步到达的点编号。然后对于每次询问,我们倍增地往lca出跳,并累加上跳过的距离,最后累加的值就是答案了。时间复杂度为O((N+Q)logN)。

离线。借助于树上差分的做法,用dis(x)表示x到根的距离,那么dist(u,v)=(dis(u)-dis(lca))+(dis(v)-dis(lca))。lca也可以用离线的Tarjan算法求,Tarjan的过程中顺便就可以处理出dis数组了。时间复杂度为O(N+Q)

附上离线做法的代码:(由于个人习惯,代码中的m就是题目的q)

#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 1001
using namespace std; struct edge{
int to,dis,next;
edge(){}
edge(const int &_to,const int &_dis,const int &_next){ to=_to,dis=_dis,next=_next; }
}e[maxn<<1];
int head[maxn],k;
struct question{
int to,lca,next;
question(){}
question(const int &_to,const int &_next){ to=_to,next=_next; }
}q[maxn<<1];
int qhead[maxn],qk; int dis[maxn],fa[maxn];
bool vis[maxn];
int n,m; inline int read(){
register int x(0),f(1); register char c(getchar());
while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
inline void add(const int &u,const int &v,const int &w){ e[k]=edge(v,w,head[u]),head[u]=k++; }
inline void link(const int &u,const int &v){ q[qk]=question(v,qhead[u]),qhead[u]=qk++; } int get(int x){ return x==fa[x]?x:fa[x]=get(fa[x]); }
void tarjan(int u){
vis[u]=true,fa[u]=u;
for(register int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(vis[v]) continue;
dis[v]=dis[u]+e[i].dis;
tarjan(v),fa[v]=u;
}
for(register int i=qhead[u];~i;i=q[i].next){
int v=q[i].to;
if(vis[v]) q[i].lca=q[i^1].lca=get(v);
}
} int main(){
memset(head,-1,sizeof head),memset(qhead,-1,sizeof qhead);
n=read(),m=read();
for(register int i=1;i<n;i++){
int u=read(),v=read(),w=read();
add(u,v,w),add(v,u,w);
}
for(register int i=1;i<=m;i++){
int u=read(),v=read();
link(u,v),link(v,u);
} tarjan(1);
for(register int i=0;i<qk;i+=2){
int u=q[i].to,v=q[i^1].to,lca=q[i].lca;
printf("%d\n",dis[u]+dis[v]-2*dis[lca]);
}
return 0;
}

[usaco2008 Oct]Pasture Walking 牧场旅行的更多相关文章

  1. LCA || BZOJ 1602: [Usaco2008 Oct]牧场行走 || Luogu P2912 [USACO08OCT]牧场散步Pasture Walking

    题面:[USACO08OCT]牧场散步Pasture Walking 题解:LCA模版题 代码: #include<cstdio> #include<cstring> #inc ...

  2. BZOJ1602: [Usaco2008 Oct]牧场行走

    1602: [Usaco2008 Oct]牧场行走 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1084  Solved: 556[Submit][St ...

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

    1602: [Usaco2008 Oct]牧场行走 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 379  Solved: 216[Submit][Sta ...

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

    一棵树..或许用LCA比较好吧...但是我懒...写了个dijkstra也过了.. ---------------------------------------------------------- ...

  5. 1602: [Usaco2008 Oct]牧场行走

    1602: [Usaco2008 Oct]牧场行走 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 1211  Solved: 616 [Submit][ ...

  6. bzoj1602 / P2912 [USACO08OCT]牧场散步Pasture Walking(倍增lca)

    P2912 [USACO08OCT]牧场散步Pasture Walking 求树上两点间路径--->lca 使用倍增处理lca(树剖多长鸭) #include<iostream> # ...

  7. 【bzoj1602】[Usaco2008 Oct]牧场行走

    1602: [Usaco2008 Oct]牧场行走 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1793  Solved: 935[Submit][St ...

  8. 洛谷P2912 [USACO08OCT]牧场散步Pasture Walking [2017年7月计划 树上问题 01]

    P2912 [USACO08OCT]牧场散步Pasture Walking 题目描述 The N cows (2 <= N <= 1,000) conveniently numbered ...

  9. bzoj1601: [Usaco2008 Oct]灌水

    经典延伸最小生成树问题... #include<cstdio> #include<cstring> #include<cctype> #include<alg ...

随机推荐

  1. 手写开源ORM框架介绍

    手写开源ORM框架介绍 简介 前段时间利用空闲时间,参照mybatis的基本思路手写了一个ORM框架.一直没有时间去补充相应的文档,现在正好抽时间去整理下.通过思路历程和代码注释,一方面重温下知识,另 ...

  2. 【PY从0到1】第一节 安装与界面介绍

    本系列是介绍如何用Python进行股票量化交易的课程. 课程内容以记录Python零基础学员从最简单的Python下载及安装开始,到最后能熟练运用Python进行量化交易的专业人员的成长历程.旨在打造 ...

  3. Flink连接器-批处理-读写Hbase

    Flink批处理与hbase的读写 source-hbase 父类 是模仿官方写的. import org.apache.flink.api.common.io.LocatableInputSplit ...

  4. Getting unknown property: common\models\Teacher::auth_Key

    找了一个半小时,不知道为什么会缺少这个属性,数据库里面的字段明明都是有的. 然后随后找到了原因,是因为key中的k大写了,所以无法识别这个属性.把自己坑到了,以此为戒,以后多注意细节问题

  5. 2020年“感恩杯”台州学院第十三届大学生程序设计竞赛D、H、I题解(后续补充)

    D题:小z与他的袜子 描述 小z每天会穿一双新袜子. 开始他的衣柜里有n双袜子,袜子会从1-n进行编号.每天早上他都会从衣柜里拿编号最小的袜子来穿.每天晚上他会把今天穿的袜子扔进篮子里,如果篮子里有n ...

  6. 2.mysql explain命令详解

    EXPLAIN详解 SQL编写和解析 编写过程 select-distinct-from-join-on-where-group by-having-order by-limit- 解析过程 from ...

  7. JVM笔记【1】-- 运行时数据区

    目录 (一)java内存区域管理 1.1 程序计数器 1.2 虚拟机栈 1.3 本地方法栈 1.4 java堆 1.5 方法区 1.5.1 运行时常量池 (二)直接内存 (一)java内存区域管理 C ...

  8. 5. Longest Palindromic Substring最大回文子串

    int sta = 0; int max = 1; public String longestPalindrome(String s) { /* 判断回文有两种: 1.最大回文子序列求长度: 用动态规 ...

  9. FSMC全称“静态存储器控制器”。

    FSMC全称"静态存储器控制器". 使用FSMC控制器后,可以把FSMC提供的FSMC_A[25:0]作为地址线,而把FSMC提供的FSMC_D[15:0]作为数据总线. (1)当 ...

  10. Linux服务器上搭建测试环境(war包+tomcat)

    悟空CRM项目环境部署(Java war项目) 在/root目录下创建一个文件夹(名字自取). ls命令查看一下是否创建成功,看到了新建的文件夹说明创建成功. tomcat和war包的准备:可以使用X ...