HDU 2586 How far away ? (LCA)
题目链接: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)的更多相关文章
- HDU 2586 How far away ? (LCA,Tarjan, spfa)
题意:给定N个节点一棵树,现在要求询问任意两点之间的简单路径的距离,其实也就是最短路径距离. 析:用LCA问题的Tarjan算法,利用并查集的优越性,产生把所有的点都储存下来,然后把所有的询问也储存下 ...
- HDU - 2586 How far away ?(LCA模板题)
HDU - 2586 How far away ? Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & ...
- hdu 2586 How far away ?倍增LCA
hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增 ...
- 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 ...
- HDU 2586.How far away ?-离线LCA(Tarjan)
2586.How far away ? 这个题以前写过在线LCA(ST)的,HDU2586.How far away ?-在线LCA(ST) 现在贴一个离线Tarjan版的 代码: //A-HDU25 ...
- HDU 2586 How far away ?(LCA在线算法实现)
http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:给出一棵树,求出树上任意两点之间的距离. 思路: 这道题可以利用LCA来做,记录好每个点距离根结点的 ...
- HDU 2586 How far away ?(LCA模板 近期公共祖先啊)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n houses in the vi ...
- HDU 2586 How far away ?【LCA模板题】
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:给你N个点,M次询问.1~N-1行输入点与点之间的权值,之后M行输入两个点(a,b)之间的最 ...
- hdu 2586 How far away ? 带权lca
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) P ...
随机推荐
- [58 Argo]58同城开源web框架Argo搭建实践
无意间听说58开源的消息(Long long ago),我辈欣喜异常. 一方面感谢开源同仁的辛苦劳动,另一方面也为我辈在互联网技术实践圈外的人提供了一条实践的渠道. 我迫不及待的从github上dow ...
- 关于<img>标签与文字垂直居中
要让左边的图片与后面的文字居中,如下效果 HTML代码: <img class="iconCls" alt="最新客户端" src="${bas ...
- windows2003 IIS6网络负载平衡设置
问题 随着计算机技术的不断发展,单台计算机的性能和可靠性越来越高.但现实中还是有许多应用是单台计算机难以达到,例如: 1.银行存储用户数据的数据库服务器必须保证24小时不间断的运转,并在发生严重硬件故 ...
- WIN7开无线
可以的,WIN7自身就带有这个功能的,不过默认是不开启的,也可以下载一个软件来弄.1.请却仍您使用的操作系统是微软的Windows 7或者Windows server 2008 R2,正版盗版皆可.( ...
- MPI编程的常用接口速查
获取当前时间 在插入MPI提供的头文件后,可以获得获取时间的函数. double MPI_Wtime(void) 取得当前时间, 计时的精度由 double MPI_Wtick(void) 取得作为对 ...
- poj 3211 Washing Clothes
// 题意 :夫妻两洗衣服,衣服有m种颜色,每种颜色又有若干件,每件衣服洗完需要特定的时间,要求每种颜色放在一起洗,洗完才能洗其他衣服.最后问洗完需要的最少时间// 将衣服按颜色分类 然后求出每种颜色 ...
- dos文件批量转换成unix文件
对于经常在windows环境下和linux环境同时使用的文件(如在windows系统下编写,在linux环境下编译的文件), 常常存在这样的问题:由于两种系统的格式文件格式不同,导致程序出现不期望的问 ...
- Java应用调优指南之-工具篇
1. 土法调优两大件 先忆苦思甜,一般人在没有Profile工具的时候,调优的两大件,无非Heap Dump 与 Thread Dump. 1.1 Heap Dump jmap -dump:live, ...
- 浅析基层检察院派驻乡镇检察室的健康发展 z
时间:2011-03-22 10:08 作者:祝志方 新闻来源:正义网 一.前言 在我国,基层检察院派驻乡镇检察室的发展经过了一个曲折发展的历程,上世纪80年代,随着经济社会的发展,一批乡镇检察室应运 ...
- A Spy in the Metro
题意: n个车站,已知到达相邻车站的时间,有m1辆车从1站出发已知发车时间,有m2辆车从n站出发已知发车时间,求从1到达n所需等车的总时间最小. 分析: 有三种情况,在原地等,乘左到右的车,乘右到左的 ...