题目描述

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. html 02-浏览器的介绍

    02-浏览器的介绍 #常见的浏览器 浏览器是网页运行的平台,常见的浏览器有谷歌(Chrome).Safari.火狐(Firefox).IE.Edge.Opera等.如下图所示: 我们重点需要学习的是 ...

  2. 逆袭故事|从“点点点”到月薪17K,这个女孩子做到啦

    姓:XXX,XX VIP 学员,一名自动化测试工程师!之前在某大型培训机构转行学习软件测试时就是木子老师的学生,她也一直关注木子老师的动态,后来知道木子老师打算开设测试开发高级提升班,等开了班就报名了 ...

  3. Centos7.6上部署Supervisor来监控和操作各类服务

    supervisor    是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,不支持Windows系统.它可以很方便的监听.启动.停止.重启一个 ...

  4. Azure Service Bus(一)入门简介

    一,引言 今天开始学习新的内容 Azure Service Bus(服务总线),其实也叫 "云消息服务",和 RabbitMQ,KafKa的一样都是作为消息通信服务,但是它们直接还 ...

  5. CentOS7离线安装mysql5.6

    下载mysql5.6,系统选择redhat,版本选择RHEL7,下载RPM Bundle后得到一个tar文件.这里得到文件MySQL-5.6.44-1.el7.x86_64.rpm-bundle.ta ...

  6. Mybatis 动态sql if 判读条件等于一个数字

    在Mybatis中 mapper中 boolean updateRegisterCompanyFlag(@Param(value = "companyId") String com ...

  7. MySQL全面瓦解15:视图

    概述 很多时候,我们会有一些很复杂的数据库操作,比如整合用户的行为数据,那这些数据可能包含用户的餐饮.生活日用.充值消费.交通出行.通讯物流.交通出行.医疗保健.住房物业.运动健康... 基于此,我们 ...

  8. sklearn中的SGDClassifier

    常用于大规模稀疏机器学习问题上 1.优点: 高效 简单 2.可以选择损失函数 loss="hinge": (soft-margin)线性SVM. loss="modifi ...

  9. .NET 5 开源工作流框架elsa技术研究

    今天假期第一天,研究了.NET 5开源工作流框架elsa,现在分享给大家. 一.框架简介 elsa是一个开源的.NET Standard 工作流框架,官方网站:https://elsa-workflo ...

  10. 迭代器设计模式,帮你大幅提升Python性能

    大家好,我们的git专题已经更新结束了,所以开始继续给大家写一点设计模式的内容. 今天给大家介绍的设计模式非常简单,叫做iterator,也就是迭代器模式.迭代器是Python语言当中一个非常重要的内 ...