HDU 2586 How far away ?(LCA)

原创 2015年11月17日 22:41:54

该题是一道比较基础的LCA(最近公共祖先),也就是快速求出树上任意两个点的最近公共祖先, 然后顺便维护边权值(每个结点到root的距离),就可以快速求出任意两个结点的距离了。

细节参见代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
using namespace std;
typedef long long ll;
const double eps = 1e-6;
const int INF = 1000000000;
const int maxn = 40000+5;
const int maxq = 200+5;
int T,n,u,v,k,m;
ll dist[maxn];
int f[maxn],answer[maxq], h[maxn], tt, q, root;
int _find(int x) {
    if(f[x] == -1) return x;
    return f[x] = _find(f[x]);
}
void bing(int u, int v) {
    int t1 = _find(u);
    int t2 = _find(v);
    if(t1 != t2) f[t1] = t2;
}
bool vis[maxn], flag[maxn];
int ancestor[maxn];
struct Edge {
    ll to, next, dist;
}edge[maxn*2];
int head[maxn], tot;
void addedge(int u, int v, int dist) {
    edge[tot].to = v;
    edge[tot].dist = dist;
    edge[tot].next = head[u];
    head[u] = tot++;
}
struct Query {
    int q, next, index;
}query[maxq*2];
void add_query(int u, int v, int index) {
    query[tt].q = v;
    query[tt].next = h[u];
    query[tt].index = index;
    h[u] = tt++;
    query[tt].q = u;
    query[tt].next = h[v];
    query[tt].index = index;
    h[v] = tt++;
}
void init() {
    tot = 0;
    memset(flag, false, sizeof(flag));
    memset(head, -1, sizeof(head));
    memset(dist, 0, sizeof(dist));
    tt = 0;
    memset(h, -1, sizeof(h));
    memset(vis, false, sizeof(vis));
    memset(f, -1, sizeof(f));
    memset(ancestor, 0, sizeof(ancestor));
}
void LCA(int u) {
    ancestor[u] = u;
    vis[u] = true;
    for(int i = head[u]; i != -1; i = edge[i].next) {
        int v = edge[i].to;
        if(vis[v]) continue;
        dist[v] = dist[u] + edge[i].dist;
        LCA(v);
        bing(u, v);
        ancestor[_find(u)] = u;
    }
    for(int i = h[u]; i != -1; i = query[i].next) {
        int v = query[i].q;
        if(vis[v]) {
            answer[query[i].index] = ancestor[_find(v)];
        }
    }
}
struct node{
    int u, v;
}a[maxq];
int main() {
    scanf("%d",&T);
    while(T--) {
        scanf("%d%d",&n,&m);
        init();
        for(int i=0;i<n-1;i++) {
            scanf("%d%d%d",&u,&v,&k);
            flag[v] = true;
            addedge(u, v, k);
            addedge(v, u, k);
        }
        for(int i=0;i<m;i++) {
            scanf("%d%d",&a[i].u,&a[i].v);
            add_query(a[i].u,a[i].v,i);
        }
        for(int i=1;i<=n;i++) {
            if(!flag[i]) {
                root = i; break;
            }
        }
        LCA(root);
        for(int i=0;i<m;i++) {
            int lca = answer[i], u = a[i].u , v = a[i].v;
            printf("%I64d\n",dist[u]+dist[v]-2*dist[lca]);
        }
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

树链剖分小结

树链剖分,计算机术语,指一种对树进行划分的算法,它先通过轻重边剖分将树分为多条链,保证每个点属于且只属于一条链,然后再通过数据结构(树状数组、SBT、SPLAY、线段树等)来维护每一条链。 树链剖...

manacher算法

ACM退役很久了, 不过仍然喜欢解决一些很酷的算法。 至此之后, 这里将会是一个纯净的算法讨论阵地, 和比赛无关, 但是希望能将算法的原理和做法讲解明白。 很后悔在做ACM的时候没有这么做。 ...

[LCA Problem] hdu2586 How far away ?

LCA即:Lowest Common Ancestor,最近公共祖先,也就是一棵树中两个节点(这是最常用的,更普遍的,可以拓展到多个节点)同处于以另外某个节点为根的子树中,并且该根结点必须尽量靠近这两...

hdu 2586 How far away ? lca 在线和离线算法

题意:给出一棵n个节点的树,m次询问,找出u和v的距离 思路:每次对u和v找到他们的lca,并且设定一个数据机构,dis[i]表示i到根的距离,那么u和v的距离等于:dp[u] + dp[v] -...

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

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

HDU---2586-How far away(LCA)

How far away ?Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:32768KB  ...

HDU 2586 How far away ? (LCA模板题 Tarjan算法求最小公共祖先)

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

How far away? - HDU 2586 - LCA

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

hdu 2586 How far away ?(LCA 求两点距离)

How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...
  • WEYuLi
  • WEYuLi
  • 2013年08月18日 20:35
  • 574

HDU2586 How far away ? LCA_Tarjan解法

How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...
  • FTQOOO
  • FTQOOO
  • 2016年02月26日 15:55
  • 283
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU 2586 How far away ?(LCA)
举报原因:
原因补充:

(最多只允许输入30个字)