HDU2586 How far away? —— 倍增LCA
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586
How far away ?
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 16425 Accepted Submission(s): 6252
unique, since the roads are built in the way that there is a unique simple path("simple" means you can't visit a place twice) between every two houses. Yout task is to answer all these curious people.
For each test case,in the first line there are two numbers n(2<=n<=40000) and m (1<=m<=200),the number of houses and the number of queries. The following n-1 lines each consisting three numbers i,j,k, separated bu a single space, meaning that there is a road
connecting house i and house j,with length k(0<k<=40000).The houses are labeled from 1 to n.
Next m lines each has distinct integers i and j, you areato answer the distance between house i and house j.
2
3 2
1 2 10
3 1 15
1 2
2 3 2 2
1 2 100
1 2
2 1
10
25
100
100
题解:
1.可知这是一棵无根树,那么把它转化为有根树,再用倍增LCA求出每个结点到根节点的距离。
2.两点的距离:dist = dis[u] + dis[v] - 2 * dis[ LCA(u,v) ]。
3.复杂度O(nlogn)。
对倍增LCA的理解:
对于每一个结点,由于在倍增的时候,每个祖先以及每条边只会被扫过一次,不会出现重复,所以可以用倍增LCA求距离。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+7;
const int maxn = 4e4+10;
const int DEG = 20; int n, m; struct edge
{
int to, w, next;
}edge[maxn*2];
int head[maxn], tot;
int fa[maxn][DEG], deg[maxn], dis[maxn]; void add(int u, int v, int w)
{
edge[tot].to = v;
edge[tot].w = w;
edge[tot].next = head[u];
head[u] = tot++;
} void bfs(int root) //一边建树,一边求出每个节点到根节点的距离,以及深度
{
queue<int>que;
deg[root] = 0;
dis[root] = 0;
fa[root][0] = root;
que.push(root);
while(!que.empty())
{
int tmp = que.front();
que.pop();
for(int i = 1; i<DEG; i++)
fa[tmp][i] = fa[fa[tmp][i-1]][i-1];
for(int i = head[tmp]; i!=-1; i = edge[i].next)
{
int v = edge[i].to, w = edge[i].w;
if(v==fa[tmp][0]) continue;
deg[v] = deg[tmp]+1;
dis[v] = dis[tmp]+w;
fa[v][0] = tmp;
que.push(v);
}
}
} int LCA(int u, int v)
{
if(deg[u]>deg[v]) swap(u,v);
int hu = deg[u], hv = deg[v];
int tu = u, tv = v;
for(int det = hv-hu, i = 0; det; det>>=1, i++)
if(det&1)
tv = fa[tv][i];
if(tv==tu) return tu;
for(int i = DEG-1; i>=0; i--)
{
if(fa[tu][i]==fa[tv][i]) continue;
tu = fa[tu][i];
tv = fa[tv][i];
}
return fa[tu][0];
} int main()
{
int T;
cin>>T;
while(T--)
{
tot = 0;
ms(head, -1);
scanf("%d%d",&n,&m);
for(int i = 1; i<n; i++)
{
int u, v, w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
} bfs(1);
for(int i = 0; i<m; i++)
{
int u, v;
scanf("%d%d",&u,&v);
printf("%d\n", dis[u]+dis[v]-2*dis[LCA(u,v)]);
}
}
}
HDU2586 How far away? —— 倍增LCA的更多相关文章
- 洛谷P3379lca,HDU2586,洛谷P1967货车运输,倍增lca,树上倍增
倍增lca板子洛谷P3379 #include<cstdio> struct E { int to,next; }e[]; ],anc[][],log2n,deep[],n,m,s,ne; ...
- [板子]倍增LCA
倍增LCA板子,没有压行,可读性应该还可以.转载请随意. #include <cstdio> #include <cstring> #include <algorithm ...
- 洛谷P3128 [USACO15DEC]最大流Max Flow [倍增LCA]
题目描述 Farmer John has installed a new system of pipes to transport milk between the stalls in his b ...
- Gym100685G Gadget Hackwrench(倍增LCA)
题目大概说一棵边有方向的树,q个询问,每次询问结点u是否能走到v. 倍增LCA搞即可: 除了par[k][u]表示u结点往上走2k步到达的结点, 再加上upp[k][u]表示u结点往上走2k步经过边的 ...
- Codeforces 418d Big Problems for Organizers [树形dp][倍增lca]
题意: 给你一棵有n个节点的树,树的边权都是1. 有m次询问,每次询问输出树上所有节点离其较近结点距离的最大值. 思路: 1.首先是按照常规树形dp的思路维护一个子树节点中距离该点的最大值son_di ...
- hdu 4674 Trip Advisor(缩点+倍增lca)
花了一天半的时间,才把这道题ac= = 确实是道好题,好久没敲这么长的code了,尤其是最后的判定,各种销魂啊~ 题目中给出的条件最值得关注的就是:每个点最多只能在一个环内->原图是由一个个边连 ...
- Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序
题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s 内存限制:512.0MB 总提交次数:196 AC次数:65 平均分: ...
- codevs 1036 商务旅行 (倍增LCA)
/* 在我还不知道LCA之前 暴力跑的SPFA 70分 三个点TLE */ #include<iostream> #include<cstdio> #include<cs ...
- hdu 2586 How far away ?倍增LCA
hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增 ...
随机推荐
- C# 生成二维码(带Logo)
C# 生成二维码(带Logo) 第一种方式 我们需要引用 ThoughtWorks.QRCode.dll 生成带logo二维码(framework4.0以上) 下载地址:https://pan.ba ...
- Java---详解方法传值问题
过程解析: 1.首先执行int[] arr={3,5,6,1,7,9,0},遇到数组先执行等式右边的,{3,5,6,1,7,9,0}会在堆内存中开辟一块空间,分成7小块,下标分别从0~6,先进行系统初 ...
- awk如何区分shell脚本传进来的参数和自身的参数?awk如何获取shell脚本传进来的参数;awk中如何执行shell命令
问题:对于shell脚本,$0表示脚本本身,$1表示脚本的第一个参数,$2……依次类推:对于awk,$1表示分割后的第一个字段,$2……依次类推.那么对于shell脚本中的awk如何区分两者呢? 答案 ...
- python 工具 二进制文件处理之——去掉指定长度数据包头
包头48bit 数据98464 ...如此循环: piece_size = 48 piece_size1 = 98464 with open("C:\\Users\\Administrato ...
- C++简单介绍
一.怎样用C++的源文件产生一个可运行程序 一个C++程序由一个或者多个编译单元组成.每一个编译单元都是一个独立的源码文件.一般是一个带.cpp的文件,编译器每次编一个文件编译单元,生成一个以.obj ...
- Crtmp Server 几个关键流程
最近在阅读Crtmp Sever 源码,有些关键流程记录下来,以备以后查阅.假设rtmp播放地址是"rtmp://127.0.0.1/live/mystream live=1" 1 ...
- MGTemplateEngine 模版发动机简单使用
https://github.com/nxtbgthng/MGTemplateEngine MGTemplateEngine 模版引擎 MGTemplateEngine比較象 PHP 中的 Smart ...
- wmware搬家
由于D盘空间不足D:\Users\Documents\Virtual Machines文件夹剪切至E:\Virtual Machines. 先关闭虚拟机 然后剪切 直接通过icon无法打开 先运行E: ...
- Tomcat Context 组件介绍(转载)
来源:http://diecui1202.iteye.com/blog/1037370 Context代表一个Web应用,它运行在某个指定的虚拟主机(Host)上:每个Web应用都是一个WAR文件,或 ...
- Linux 中权限的再讨论( 下 )
前言 上篇随笔讲述了Linux中权限的大致实现机制以及目录权限的相关规则.本文将讲解Linux中的三种特殊权限:SUID,SGID,Sticky权限.看完这两篇文章,你一定会对Linux的权限有个更深 ...