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 思路: 针对询问次数多的时候,采取倍增 ...
随机推荐
- Oracle服务扫描工具Oscanner
Oracle服务扫描工具Oscanner Oracle是甲骨文公司推出的关系型数据库,适用于中大规模数据存储,如大型企业.电信.银行等行业.Kali Linux集成了Oracle服务扫描专向工具O ...
- git常用语句
1.安装git,也适用于升级 yum -y install gcc zlib-devel openssl-devel curl-devel \ expat-devel gettext-devel pe ...
- BZOJ 1008: [HNOI2008]越狱 组合数学
原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1008 题解: 就很傻逼的组合数学啊... $$ans=M^N-M*(M-1)^{(N-1) ...
- POJ 2253 Frogger Floyd
原题链接:http://poj.org/problem?id=2253 Frogger Time Limit: 1000MS Memory Limit: 65536K Total Submissi ...
- 精简版的MySQL制作步骤
1.删除所有的目录,只保留 datasharebin 2.删除BIN下面除以下三个文件之外的所有文件: libmysql.dll(MYSQL5中的文件,在MYSQL5.5中不存在)mysqladmin ...
- Mac下export生效
在Terminal下用export PS1=XXX 修改完后,本次生效,但是重新启动Teminal后又恢复到默认格式.如何才能永久保存自定义的提示符格式呢? 1,~下面本来没有 .bash_pro ...
- Android常见的三种内部类
在java里类中再定义类,这种在其他类内部类叫做内部类,在Android开发里最常见有三种内部类分别是(成员内部类.方法内部类.匿名内部类) 一.成员内部类 1 public class Test { ...
- 使用cacheBuilder时捕获内部指定异常
由于cacheBuilder是另起线程获取,对call方法中的抛出的异常进行了封装.所以我们在最外层捕获时是无法直接指定异常类型捕获的, 获取异常的原因判断实例类型 public static voi ...
- PCB中地线和电源线的布线规则
电源. 地线的布置考虑不周到而引起干扰,使产品的性能下降,严重时会降低产品的成功率.要把电源线和地线处理好,将电源线和地线所产生的噪音干扰降到最低限度,以保证产品的质量.一.电源线和地线的布线规则1) ...
- 【程序猿联盟】官网上线啦!coderunity.com
wx_fmt=jpeg" alt="" style="max-width:100%; height:auto!important"> 内容简单介 ...