牧场行走(LCA)
好吧,这题很有意思。。
第一眼撇的时候还以为是(SPFA)呜。。。。
然后发现要Q次询问就想到了LCA
但是发现不是求LCA。。
于是想到了一个神奇的定律:
两点的LCA一定在u到v的最短路上。。
并且也一定在两点与根节点的路上。
所以用dis[a]+dis[b]-2*dis[LCA(a,b)]就得到答案啦!
这道题有一个坑点!注意!
我们先来看一个测试:
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main(){
int x,y;
scanf("%d%d",&x,&y);
int k1=(int)(log(y-x+1.0)/log(2.0));
int k2=;
while(<<(k2+)<=y-x+)k2++;
printf("%d %d",k1,k2);
}
这看起来是等价的。。但是。。
输入:1 8
输出:2 3
恩,你没有看错,就是2、3.
事实是这样的:C++ 计算log(8)/log(2)时,得到的答案为(double)2.9999996。
强制转换为int后,变成了2;
但是这样就可以了QAQ
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main(){
int num;
int num2;
double k=log(8.0)/log(2.0);
num2=k;
printf("%d",num2);
}
恩,这样就是啦awa
万恶的C++。。。
下面贴代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
struct data{
int to,next,value;
}g[];
int head[];
bool qs[];
int id[];
int vs[];
int depth[];
int dp[][];
int dd[];
int dfs_clock=;
int n,q,num=,root;
void ins(int a,int b,int v){
g[++num].next=head[a];
head[a]=num;
g[num].to=b;
g[num].value=v;
}
void dfs(int u,int fa,int d){
id[u]=dfs_clock;
vs[dfs_clock]=u;
depth[dfs_clock++]=d;
for(int i=head[u];i;i=g[i].next)
{
int v=g[i].to;
if(v==fa) continue;
dd[v]=dd[u]+g[i].value;
dfs(v,u,d+);
vs[dfs_clock]=u;
depth[dfs_clock++]=d;
}
}
void RMQ(int nn){
for(int i=;i<=nn;i++)
dp[i][]=i;
for(int j=;(<<j)<=nn;j++)
for(int i=;i+(<<j)-<=nn;i++)
{
int a=dp[i][j-];
int b=dp[i+(<<(j-))][j-];
if(depth[a]<=depth[b])
dp[i][j]=a;
else
dp[i][j]=b;
}
}
int cal(int x,int y){
double k2=log(y-x+1.0)/log(2.0);
int k=k2;
int a=dp[x][k];
int b=dp[y-(<<k)+][k];
if(depth[a]<=depth[b])
return a;
else return b;
}
int lca(int u,int v){
int x=id[u];
int y=id[v];
if(x<y)
return vs[cal(x,y)];
else return vs[cal(y,x)];
}
int main(){
scanf("%d%d",&n,&q);
for(int i=;i<n;i++)
{
int a,b,v;
scanf("%d%d%d",&a,&b,&v);
qs[b]=;
ins(a,b,v);ins(b,a,v);
}
dfs(,,);
RMQ(dfs_clock-);
for(int i=;i<=q;i++)
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",dd[a]+dd[b]-*dd[lca(a,b)]);
}
}
不会RMQ的可以看我的传送门
当然,要打树上倍增的也是可以啦。。
代码就不贴了。
真是奇特的题目233~
牧场行走(LCA)的更多相关文章
- [BZOJ1602] [Usaco2008 Oct] 牧场行走 (LCA)
Description N头牛(2<=n<=1000)别人被标记为1到n,在同样被标记1到n的n块土地上吃草,第i头牛在第i块牧场吃草. 这n块土地被n-1条边连接. 奶牛可以在边上行走, ...
- bzoj 1602 [Usaco2008 Oct]牧场行走(LCA模板)
1602: [Usaco2008 Oct]牧场行走 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 379 Solved: 216[Submit][Sta ...
- 树讲解——牧场行走( lca )
大视野 1602: [Usaco2008 Oct]牧场行走 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1947 Solved: 1021[Sub ...
- BZOJ1602: [Usaco2008 Oct]牧场行走
1602: [Usaco2008 Oct]牧场行走 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1084 Solved: 556[Submit][St ...
- BZOJ 1602: [Usaco2008 Oct]牧场行走( 最短路 )
一棵树..或许用LCA比较好吧...但是我懒...写了个dijkstra也过了.. ---------------------------------------------------------- ...
- 1602: [Usaco2008 Oct]牧场行走
1602: [Usaco2008 Oct]牧场行走 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1211 Solved: 616 [Submit][ ...
- 【bzoj1602】[Usaco2008 Oct]牧场行走
1602: [Usaco2008 Oct]牧场行走 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1793 Solved: 935[Submit][St ...
- 【BZOJ】1602: [Usaco2008 Oct]牧场行走(lca)
http://www.lydsy.com/JudgeOnline/problem.php?id=1602 一开始以为直接暴力最短路,但是n<=1000, q<=1000可能会tle. 显然 ...
- LCA || BZOJ 1602: [Usaco2008 Oct]牧场行走 || Luogu P2912 [USACO08OCT]牧场散步Pasture Walking
题面:[USACO08OCT]牧场散步Pasture Walking 题解:LCA模版题 代码: #include<cstdio> #include<cstring> #inc ...
随机推荐
- Altium Designer使用5:AD18的DXP在什么地方?
1.在顶上的菜单栏右击
- python正则表达式02--findall()和search()方法区别,group()方法
import re st = 'asxxixxsaefxxlovexxsdwdxxyouxxde' #search()和 findall()的区别 a = re.search('xx(.*?)xxsa ...
- Hive 文件格式 & Hive操作(外部表、内部表、区、桶、视图、索引、join用法、内置操作符与函数、复合类型、用户自定义函数UDF、查询优化和权限控制)
本博文的主要内容如下: Hive文件存储格式 Hive 操作之表操作:创建外.内部表 Hive操作之表操作:表查询 Hive操作之表操作:数据加载 Hive操作之表操作:插入单表.插入多表 Hive语 ...
- js双轴柱状图
<!doctype html><html lang="en"><head> <script type="text/javascr ...
- poj2001Shortest Prefixes(trie)
Shortest Prefixes Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 18687 Accepted: 808 ...
- Java-JNA使用心得
自上个月20号,历时整整一个月,终于找到工作入职了. 然后这段时间一直看公司的框架还有业务方面的东西.其实由于给分配了一个研究Java调用C语言接口的问题,导致框架业务方面的东西还不熟,然后现在手上又 ...
- 洛谷P1451 求细胞数量
求细胞数量 题目链接 这道题大概是一个最简单的联通块的题了qwq 注意枚举起点的时候 一定不要从0开始不然你就会从0进入到了其他联通块中从而多查. 一定看清题意这道题不是同色为联通块!!! AC代码如 ...
- Java设计模式-----装饰者
对方法做增强,并不能添加新的接口方法.
- 《Cracking the Coding Interview》——第13章:C和C++——题目7
2014-04-25 20:18 题目:给定一个Node结构体,其中包含数据成员和两个Node*指针指向其他两个Node结构(还不如直接说这是个图呢).给你一个Node指针作为参数,请做一份深拷贝作为 ...
- 常用模块(time)
import time # data = time.time() # 获取时间戳# data = time.localtime() # 获取操作系统时间,也称本地时间,可传入时间戳# data = t ...