题目描述

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. react第十九单元(react+react-router-dom+redux综合案例1)

    第十九单元(react+react-router-dom+redux综合案例1) #课程目标 复习 综合练习 实战能力 #知识点 react react-router redux #授课思路 #案例和 ...

  2. Spring Cloud Ribbon之URL重构(三)

    接着前面的说,前两篇中分析了解析和动态服务列表的获取,这两步完成后那接下来要做的事就是重组解析后的URL路径和发起通信了,这一步完成应该是在前面分析的RibbonLoadBalancerClient. ...

  3. python监控文件实时批量压缩脚本

    # coding:utf-8 from shutil import make_archive import os import time # 指定需要监测的文件夹 image_path = './im ...

  4. 嵌入式开发笔记——调试组件SEGGER_RTT

    一.前言 在嵌入式开发过程中,经常会通过打印输出一些调试信息来调试参数.查找问题等,通常我的做法都是使用芯片的串口硬件设备配合串口助手软件来进行调试.但是这次项目的PCB硬件设计并未预留串口调试接口, ...

  5. 查询id为键的数组

    public static function getKeyValuePairs() { $sql = 'SELECT id, name FROM ' . self::tableName() . ' O ...

  6. 2020年Spring Cloud最后一个大版本发布!

    2020年12月22日,Spring Cloud 2020.0 正式发布GA版本! 版本说明 每次Spring Cloud的大版本发布,我们都要先弄清楚,它对应的Spring Boot版本是哪个! 该 ...

  7. List<bean> 转换成List<Map>

    //将listmap转换成list实体类 List<OaAttachment>list=new ArrayList<OaAttachment>(); if(Func.isNot ...

  8. sendfile“零拷贝”和mmap内存映射

    在学习sendfille之前,我们先来了解一下浏览器访问页面时,后台服务器的大致工作流程. 下图是从用户访问某个页面到页面的显示这几秒钟的时间当中,在后台的整个工作过程. 如上图,黑色箭头所示的过程, ...

  9. Mysql大概1700W大表删除1000W左右数据,发现数据大小和索引大小并没有减少思考

    MySQL删除操作其实是假删除 因为近期在重构优化一个业务的时候 发现有一张表(send_log)数据量将近1700W 左右  占用数据大小17G,索引18G左右  而我们的核心应用在使用的时候 会去 ...

  10. IT 界那些朗朗上口的“名言

    中国有很多古代警世名言,朗朗上口,凝聚了很多故事与哲理.硅谷的互联网公司里头也有一些这样的名言,凝聚了很多公司价值观和做事的方法,对于很多程序员来说,其影响潜移默化.这里收集了一些,如下. Stay ...