题目描述

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. Hive通过Jdbc获取表的字段信息

    参考代码如下: /** * 按顺序返回字段 * desc table的返回结果形式如下: hive> describe ind01acoM; OK acq_ins_id_cd string cu ...

  2. 【Java】Java Win10环境搭建--JDK、Eclipse

    win10安装Java JDK环境及Eclipse安装使用(Hello world) win10环境下安装Java环境,对于小白来说简直是头疼,因为Java内部环境有着JDK和JRE两块,互相牵扯着很 ...

  3. iframe高度自动随着子页面的高度变化而变化(不止要在iframe标签里加上this.height=this.contentWindow.document.body.scrollHeight)

    最近使用iframe整合页面遇到一些难题,走了很多弯路才解决,借此记录一下: 1 <!-- 页面主体内容 --> 2 <div class="iframe-wrapper& ...

  4. python爬虫之解析链接

    解析链接 1. urlparse() & urlunparse() urlparse() 是对url链接识别和分段的,API用法如下: urllib.parse.urlparse(urlstr ...

  5. iOS 集成友盟分享图片链接为http时无法加载问题解决

    一.问题描述 UMShareWebpageObject *obj = [UMShareWebpageObject shareObjectWithTitle:title descr:shareText ...

  6. 自定义 demo 集合

    各种写着玩的自定义控件demo 有时网上看到一些比较有意思的开源项目,有时间的话就会自己也撸一个出来,但是一般只关注实现样式.动画等,不会太去细致完整地完成,俗称占个坑~ 持续更新中... githu ...

  7. SpringBoot 内嵌容器的比较

    Spring Boot内嵌容器支持Tomcat.Jetty.Undertow.为什么选择Undertow? 这里有一篇文章,时间 2017年1月26日发布的: 参考 Tomcat vs. Jetty ...

  8. 【代码周边】-GitHub笔记

    ------------恢复内容开始------------ 程序员的宝库github是个好东西,其中开源的项目足够我们的使用,但是如何去精准的获取我们的项目是很多初学者的问题.特别是英语不好的我,一 ...

  9. 个人总结的一些C++基础理论

    我自己整理的一些C++基础理论知识,面试的同学可以用到: 主要是针对那些基础理论知识比较薄弱的同学吧,希望会对大家面试有些帮助,排版什么的有点乱,大家多多包涵: 往期经典: 北漂95后的2020 给北 ...

  10. Java学习日报7.22

    //3.2   逆向输出三位整数!    7.22 package 三个和尚比身高1; import java.util.Scanner; public class Demo1{ @SuppressW ...