Hdu 2586 How far away ?

来源:互联网 发布:淘宝销售数据统计 编辑:程序博客网 时间:2024/06/05 05:22

题目链接


http://acm.hdu.edu.cn/showproblem.php?pid=2586
 题目是说给定一张图,知道n - 1条边让两点相连,但是不会有两条路让两点相连,那么就是一颗树。然后又给定m个询问,问a, b两点间最短距离。
 那么使用LCA求最短公共父节点即可,并且增加一个容器存放到树根的值,tarjan的时候增加一个转移值以报存其父节点离树根的距离。之后增加一个容器保存询问的顺序即可离线化处理询问。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <cmath>#define rep(i, s, t) for(int i = s;i <= t;i++)#define rap(i, s, t) for(int i = s;i >= t;i--)using namespace std;int n, m;const int M = 100004;vector<int>tree[M];vector<int>query[M];vector<int>queid[M];vector<int>worth[M];bool vis[M];int f[M];int ancestor[M];int dis[M];int ans[M];int findd(int x){    return x == f[x]?f[x]:f[x] = findd(f[x]);}void uni(int x, int y){    x = findd(x);    y = findd(y);    if(x != y)        f[x] = y;}void init(){    rep(i, 0, n){        vis[i] = false;        tree[i].clear();        query[i].clear();        worth[i].clear();        queid[i].clear();        f[i] = i;        dis[i] = 0;        ans[i] = 0;    }}void input_tree(){    rep(i, 1, n - 1){        int a, b, c;        scanf("%d%d%d", &a, &b, &c);        tree[a].push_back(b);        worth[a].push_back(c);        tree[b].push_back(a);        worth[b].push_back(c);    }}void input_query(){    rep(i, 1, m)    {        int a, b;        scanf("%d%d", &a, &b);        query[a].push_back(b);        queid[a].push_back(i);        query[b].push_back(a);        queid[b].push_back(i);    }}void tarjan(int x, int value){    dis[x] = value;    vis[x] = true;    rep(i, 0, (int)tree[x].size() - 1){        int v = tree[x][i];        if(vis[v] == true)            continue;        tarjan(v, value + worth[x][i]);        uni(x, v);        ancestor[findd(x)] = x;    }    rep(i, 0, (int)query[x].size() - 1){        int v = query[x][i];        if(vis[v])            ans[queid[x][i]] = dis[x] + dis[v] - 2 * dis[ancestor[findd(v)]];    }}int main(){    int t;    scanf("%d", &t);    while(t--)    {        scanf("%d%d", &n, &m);        init();        input_tree();        input_query();        tarjan(1, 0);        rep(i, 1, m)            printf("%d\n", ans[i]);    }    return 0;}
原创粉丝点击