BZOJ 1602 Usaco2008 Oct 牧场行走 倍增LCA

来源:互联网 发布:沙县小吃知乎 编辑:程序博客网 时间:2024/05/17 04:43

题目大意

给出一个树,多次询问两点之间的距离。

思路

这个题存在的意义是什么?

CODE

#define _CRT_SECURE_NO_WARNINGS#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAX 1010using namespace std;int head[MAX], total;int _next[MAX << 1], aim[MAX << 1], length[MAX << 1];int points, asks;inline void Add(int x, int y, int len){    _next[++total] = head[x];    aim[total] = y;    length[total] = len;    head[x] = total;}int father[MAX][20], len[MAX][20];int deep[MAX];void DFS(int x, int last){    deep[x] = deep[last] + 1;    for(int i = head[x]; i; i = _next[i]) {        if(aim[i] == last)  continue;        father[aim[i]][0] = x;        len[aim[i]][0] = length[i];        DFS(aim[i], x);    }}void SparseTable(){    for(int j = 1; j <= 19; ++j)        for(int i = 1; i <= points; ++i) {            father[i][j] = father[father[i][j - 1]][j - 1];            len[i][j] = len[i][j - 1] + len[father[i][j - 1]][j - 1];        }}inline int GetLCA(int x, int y){    if(deep[x] < deep[y])   swap(x, y);    int re = 0;    for(int i = 19; ~i; --i)        if(deep[father[x][i]] >= deep[y]) {            re += len[x][i];            x = father[x][i];        }    if(x == y)  return re;    for(int i = 19; ~i; --i)        if(father[x][i] != father[y][i]) {            re += len[x][i] + len[y][i];            x = father[x][i];            y = father[y][i];        }    re += len[x][0] + len[y][0];    return re;}int main(){    cin >> points >> asks;    for(int x, y, z, i = 1; i < points; ++i) {        scanf("%d%d%d", &x, &y, &z);        Add(x, y, z), Add(y, x, z);    }    DFS(1, 0);    SparseTable();    for(int x, y, i = 1; i <= asks; ++i) {        scanf("%d%d", &x, &y);        printf("%d\n", GetLCA(x, y));    }    return 0;}
0 0