您的位置:首页 > 其它

倍增法LCA hdu2586 How far away ?

2015-12-08 20:46 375 查看
传送门:点击打开链接

题意:给你一棵树,每条边有权值,求两点之间的最短距离

思路:裸LCA。这里主要练习一下倍增法,感觉这种思路和代码实现很简单,而且能感觉实用性很大的,很值得学习

倍增法要理解对2的次方的枚举顺序

如果是要走固定步数,那么顺序枚举与i位与为1就行

如果是要求一个临界位置,那么要从大到小枚举

#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define fuck(x) cout<<"["<<x<<"]"
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)
using namespace std;
typedef long long LL;

const int MX = 1e5 + 5;
const int M = 20;

struct Edge {
int v, nxt, cost;
} E[MX];
int Head[MX], rear;
void edge_init() {
rear = 0;
memset(Head, -1, sizeof(Head));
}
void edge_add(int u, int v, int cost) {
E[rear].v = v;
E[rear].cost = cost;
E[rear].nxt = Head[u];
Head[u] = rear++;
}

int dep[MX], dist[MX], fa[MX][M], n;
void DFS(int u, int _dist, int _dep, int _fa) {
dist[u] = _dist; dep[u] = _dep; fa[u][0] = _fa;
for(int i = Head[u]; ~i; i = E[i].nxt) {
int v = E[i].v;
if(v == u || v == _fa) continue;
DFS(v, _dist + E[i].cost, _dep + 1, u);
}
}
void presolve() {
DFS(1, 0, 0, 1);
for(int i = 1; i < M; i++) {
for(int j = 1; j <= n; j++) {
fa[j][i] = fa[fa[j][i - 1]][i - 1];
}
}
}
int LCA(int u, int v) {
while(dep[u] != dep[v]) {
if(dep[u] < dep[v]) swap(u, v);
int d = dep[u] - dep[v];
for(int i = 0; i < M; i++) {
if(d >> i & 1) u = fa[u][i];
}
}
if(u == v) return u;
for(int i = M - 1; i >= 0; i--) {
if(fa[u][i] != fa[v][i]) {
u = fa[u][i];
v = fa[v][i];
}
}
return fa[u][0];
}
int query(int u, int v) {
return dist[u] + dist[v] - dist[LCA(u, v)] * 2;
}

int main() {
int T, m; //FIN;
scanf("%d", &T);
while(T--) {
edge_init();
scanf("%d%d", &n, &m);
for(int i = 1; i <= n - 1; i++) {
int u, v, cost;
scanf("%d%d%d", &u, &v, &cost);
edge_add(u, v, cost);
edge_add(v, u, cost);
}
presolve();

while(m--) {
int u, v;
scanf("%d%d", &u, &v);
printf("%d\n", query(u, v));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: