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;
}


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

HDU 2586 How far away?(LCA使用详解)

LCA、并查集、动态规划、深度优先搜索、哈希、RMQ、递归
  • nameofcsdn
  • nameofcsdn
  • 2016年08月17日 15:56
  • 2627

HDU-2586-How far away ?(倍增求LCA模板)

题目链接:HDU-2586-How far away ?倍增求LCA: 1.先转化成有根树。 2.dfs求出每个点的深度 3.初始化anc数组 4.倍增查询#include using nam...
  • jinglinxiao
  • jinglinxiao
  • 2017年03月28日 18:33
  • 182

倍增法LCA hdu2586 How far away ?

传送门:点击打开链接 题意:给你一棵树,每条边有权值,求两点之间的最短距离 思路:裸LCA。这里主要练习一下倍增法,感觉这种思路和代码实现很简单,而且能感觉实用性很大的,很值得学习 倍增法要理解...
  • qwb492859377
  • qwb492859377
  • 2015年12月08日 20:46
  • 1020

hdoj 2586 How far away ? 【LCA转RMQ入门题】

How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others...
  • chenzhenyu123456
  • chenzhenyu123456
  • 2015年08月09日 11:05
  • 392

hdu 2586 How far away ? 最近公共祖先lca 在线算法(倍增法)/离线算法(Tarjan算法)

#pragma comment(linker, "/STACK:1024000000,1024000000") #include #include #include #include #i...
  • a601025382s
  • a601025382s
  • 2013年08月30日 16:44
  • 3791

HDU 2586 How far away ?

How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T...
  • IAccepted
  • IAccepted
  • 2015年01月24日 00:38
  • 3043

HDU 2586 How far away ?——lca

假设dis【i】为i到根节点的距离,那么u和v之间的距离为dis【u】 + dis【v】 - 2 * dis【lca(u,v)】 #include #include #include #inc...
  • hao_zong_yin
  • hao_zong_yin
  • 2017年10月11日 13:02
  • 69

HDU 2586 How far away ?(LCA模板题)

恰好最近做了强联通,用tarjan比较多,所以就上tarjan的模版来做这题。 看到别人用tarjan求LCA,用到low和dfn两个数组,我们要明白,low是用来记录某个点的根,dfn是记录某个点能...
  • llzhh
  • llzhh
  • 2017年07月19日 09:52
  • 80

HDU 2586 How far away ?【LCA】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586题意:无向图,给定边及边权重,任意两点之间都有一条唯一的道路,道路上每个点只能出现一次。给定询问,...
  • Yukizzz
  • Yukizzz
  • 2016年03月25日 00:07
  • 172

HDU 2586 How far away ?LCA Tarjan

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

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