题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586

LCA模版题。

RMQ+LCA:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <vector> using namespace std;
const int MAXN = 4e4 + ;
typedef pair<int , int>P;
vector <P> G[MAXN];
int dep[MAXN] , dis[MAXN] , par[MAXN][] , ok[MAXN]; void init(int n) {
for(int i = ; i <= n ; i++) {
G[i].clear();
ok[i] = ;
}
} void dfs(int root) {
for(int i = ; i < G[root].size() ; i++) {
dis[G[root][i].first] = dis[root] + G[root][i].second;
dfs(G[root][i].first);
}
} void dfs2(int u , int p , int d) {
dep[u] = d;
par[u][] = p;
for(int i = ; i < G[u].size() ; i++) {
dfs2(G[u][i].first , u , d + );
}
} int lca(int u , int v) {
if(dep[u] < dep[v]) {
swap(u , v);
}
for(int k = ; k < ; k++) {
if((dep[u] - dep[v]) >> k & ) {
u = par[u][k];
}
}
if(u == v)
return u;
for(int k = ; k >= ; k--) {
if(par[u][k] != par[v][k]) {
u = par[u][k];
v = par[v][k];
}
}
return par[u][];
} int main()
{
int n , m , q , v , u , d , root , t;
char op[];
scanf("%d" , &t);
while(t--) {
scanf("%d %d" , &n , &m);
init(n);
root = (n + ) * n / ;
for(int i = ; i < n - ; i++) {
scanf("%d %d %d" , &u , &v , &d);
G[u].push_back(P(v , d));
if(!ok[v]) {
root -= v;
ok[v] = ;
}
}
dfs2(root , - , );
dis[root] = ;
for(int k = ; k < ; k++) {
for(int i = ; i <= n ; i++) {
if(par[i][k] <= ) {
par[i][k + ] = ;
}
else {
par[i][k + ] = par[par[i][k]][k];
}
}
}
dfs(root);
for(int i = ; i < m ; i++) {
scanf("%d %d" , &u , &v);
printf("%d\n" , dis[u] + dis[v] - * dis[lca(u , v)]);
}
}
}

树链剖分的LCA:

 #include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 5e4 + ;
struct data {
int to , next , cost;
}edge[MAXN << ];
int head[MAXN] , cnt;
int par[MAXN] , dep[MAXN] , top[MAXN] , id[MAXN] , dis[MAXN] , size[MAXN] , son[MAXN]; void init() {
memset(head , - , sizeof(head));
cnt = ;
} inline void add(int u , int v , int cost) {
edge[cnt].to = v;
edge[cnt].next = head[u];
edge[cnt].cost = cost;
head[u] = cnt++;
}
//求size , par , son , dep
void dfs_1(int u , int p , int d) {
par[u] = p , size[u] = , son[u] = u , dep[u] = d;
for(int i = head[u] ; ~i ; i = edge[i].next) {
int v = edge[i].to;
if(v == p)
continue;
dis[v] = dis[u] + edge[i].cost; //离根的距离
dfs_1(v , u , d + );
if(size[v] > size[son[u]]) //取重儿子
son[u] = v;
size[u] += size[v];
}
}
//求top , id
void dfs_2(int u , int p , int t) { //p为父节点 t为链的祖先
top[u] = t; //链的祖先
id[u] = ++cnt; //点的顺序
if(son[u] != u) //重儿子优先
dfs_2(son[u] , u , t);
for(int i = head[u] ; ~i ; i = edge[i].next) {
int v = edge[i].to;
if(v == p || v == son[u])
continue;
dfs_2(v , u , v); //树链重新开始
}
}
//树链剖分求lca的复杂度是(nlognlogn),建议用RMQ求lca
int lca(int u , int v) {
int fu = top[u] , fv = top[v];
while(top[u] != top[v]) { //链是否相同,不同就循环
if(dep[fu] < dep[fv]) { //比较两个链的深度
v = par[fv];
fv = top[fv];
}
else {
u = par[fu];
fu = top[u];
}
}
if(dep[u] >= dep[v]) //在相同的链上
return v;
return u;
} int main()
{
int n , q , u , v , cost , x , y , z , t;
scanf("%d" , &t);
while(t--) {
scanf("%d %d" , &n , &q);
init();
for(int i = ; i < n ; ++i) {
scanf("%d %d %d" , &u , &v , &cost);
add(u , v , cost);
add(v , u , cost);
}
cnt = ;
dfs_1( , , );
dfs_2( , , );
while(q--) {
scanf("%d %d" , &x , &y);
int res = (dis[x] + dis[y] - * dis[lca(x , y)]);
printf("%d\n" , res);
}
}
}

HDU 2586 How far away ? (LCA)的更多相关文章

  1. HDU 2586 How far away ? (LCA,Tarjan, spfa)

    题意:给定N个节点一棵树,现在要求询问任意两点之间的简单路径的距离,其实也就是最短路径距离. 析:用LCA问题的Tarjan算法,利用并查集的优越性,产生把所有的点都储存下来,然后把所有的询问也储存下 ...

  2. HDU - 2586 How far away ?(LCA模板题)

    HDU - 2586 How far away ? Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & ...

  3. hdu 2586 How far away ?倍增LCA

    hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增 ...

  4. HDU 2586 How far away ?【LCA】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=2586 How far away ? Time Limit: 2000/1000 MS (Java/Oth ...

  5. HDU 2586.How far away ?-离线LCA(Tarjan)

    2586.How far away ? 这个题以前写过在线LCA(ST)的,HDU2586.How far away ?-在线LCA(ST) 现在贴一个离线Tarjan版的 代码: //A-HDU25 ...

  6. HDU 2586 How far away ?(LCA在线算法实现)

    http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:给出一棵树,求出树上任意两点之间的距离. 思路: 这道题可以利用LCA来做,记录好每个点距离根结点的 ...

  7. HDU 2586 How far away ?(LCA模板 近期公共祖先啊)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n houses in the vi ...

  8. HDU 2586 How far away ?【LCA模板题】

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:给你N个点,M次询问.1~N-1行输入点与点之间的权值,之后M行输入两个点(a,b)之间的最 ...

  9. hdu 2586 How far away ? 带权lca

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) P ...

随机推荐

  1. Codeforces Beta Round #2B(dp+数学)

    贡献了一列WA.. 数学很神奇啊 这个题的关键是怎么才能算尾0的个数 只能相乘 可以想一下所有一位数相乘 除0之外,只有2和5相乘才能得到0 当然那些本身带0的多位数 里面肯定含有多少尾0 就含有多少 ...

  2. 在Windows下通过命令行或者.bat文件统计一个目录中文件数量

    在Windows下面怎样通过命令行统计一个目录中文件的数量,或者说,如果在一个.bat文件中,统计一个目录中的文件数量? 我原来以为是不可能的,要编一个vbs程序什么的,后来到网上找了下,发现还真是可 ...

  3. poj 2886 Who Gets the Most Candies?(线段树和反素数)

    题目:http://poj.org/problem?id=2886 题意:N个孩子顺时针坐成一个圆圈且从1到N编号,每个孩子手中有一张标有非零整数的卡片. 第K个孩子先出圈,如果他手中卡片上的数字A大 ...

  4. 文件大小转换成可显示的Mb,Gb和kb方法

    public static String unitConversion(float resource) { String[] unit = new String[] { "B", ...

  5. 一个简单的ORM制作(SQL帮助类)

    一个简单的ORM制作大概需要以下几个类: SQL执行类 CURD操作类 其他酱油类 先从SQL执行类说起,可能会涉及数据库的迁移等问题,所以需要定义一个接口以方便迁移到其他数据库, 事务没提供命名,若 ...

  6. Struts2中通配符

    1.Struts2中通配符可通过请求的url路径来确定包.类.方法.返回值名. 如 <action name="*_*_*_*" class="cn.javass. ...

  7. 在linux的shell里访问一个URL

    在linux上访问一个网址有四种方法 1.elinks,用法举例: [weishusheng@centOS6 ~]$ elinks -dump http://www.baidu.com 2. wget ...

  8. 【转】Intel HEX介绍

    记录格式 Intel HEX由任意数量的十六进制记录组成.每个记录包含5个域,它们按以下格式排列: :llaaaatt[dd...]cc 每一组字母对应一个不同的域,每一个字母对应一个十六进制编码的数 ...

  9. [Everyday Mathematics]20150119

    设 $V$ 是 $n$ 维线性空间, $V_1, V_2$ 均为 $V$ 的子空间, 且 $$\bex V_1\subset V_2,\quad \dim V=10,\quad \dim V_1=3, ...

  10. C++ primer里的template用法

    来源:http://c.chinaitlab.com/cc/ccjq/200806/752604_2.html --  template 的用法    在程序设计当中经常会出现使用同种数据结构的不同实 ...