HDU - 2586 How far away ?(LCA)

题目大意:给出一张连通图,问两个点之间的距离

解题思路:LCA裸题

#include <cstdio>
#include <cstring>
#define N 40010
#define M 80010

struct Edge{
    int to, next, dis;
}E[M];

struct Question {
    int x, y;
}Q[N];

int n, m ,tot;
int head[N], dist[N], f[N], LCA[N];
bool vis[N];

void AddEdge(int u, int v, int dis) {
    E[tot].to = v; E[tot].dis = dis; E[tot].next = head[u]; head[u] = tot++;
    u = u ^ v; v = u ^ v; u = u ^ v;
    E[tot].to = v; E[tot].dis = dis; E[tot].next = head[u]; head[u] = tot++;
}

int find(int x) {
    return x == f[x] ? x : f[x] = find(f[x]);
}

void tarjan(int u) {
    vis[u] = true;
    f[u] = u; 

    for (int i = head[u]; i != -1; i = E[i].next) {
        int v = E[i].to;
        if (!vis[v]) {
            dist[v] = dist[u] + E[i].dis;
            tarjan(v);
            f[v] = u;
        }
    }
    for (int i = 0; i < m; i++) {
        if (u == Q[i].x && vis[Q[i].y])
            LCA[i] = find(Q[i].y);
        if (u == Q[i].y && vis[Q[i].x])
            LCA[i] = find(Q[i].x);
    }
}

void init() {
    memset(head, -1, sizeof(head));
    tot = 0;

    int u, v, d;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n - 1; i++) {
        scanf("%d%d%d", &u, &v, &d);
        AddEdge(u, v, d);
    }
    for (int i = 0; i < m; i++)  scanf("%d%d", &Q[i].x, &Q[i].y);

    memset(vis, 0, sizeof(vis));
}

void solve() {
    dist[1] = 0;
    tarjan(1);
    for (int i = 0; i < m; i++)
        printf("%d\n", dist[Q[i].x] + dist[Q[i].y] - 2 * dist[LCA[i]]);
}

int main() {
    int test;
    scanf("%d", &test);
    while (test--) {
        init();
        solve();
    }
    return 0;
}

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

时间: 2024-10-02 09:04:09

HDU - 2586 How far away ?(LCA)的相关文章

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

题目地址:HDU 2586 LCA第一发. 纯模板题. 偷懒用的vector,结果一直爆栈.把G++改成C++就过了.. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <se

HDU 2586 How far away ?(LCA裸题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 #include<bits/stdc++.h> #define lson rt << 1, l, m #define rson rt << 1 | 1, m + 1, r using namespace std; typedef long long ll; static const ll inf = (1 << 32); static const int

HDU 2586 How far away ? (LCA,Tarjan, spfa)

题意:给定N个节点一棵树,现在要求询问任意两点之间的简单路径的距离,其实也就是最短路径距离. 析:用LCA问题的Tarjan算法,利用并查集的优越性,产生把所有的点都储存下来,然后把所有的询问也储存下来,然后从树根开始搜索这棵树, 在搜索子树的时候,把并查集的父结点不断更新,在搜索时计算答案,d[i] 表示从根结点到 i 结点的距离,然后分别计算到两个结点的距离, 再减去2倍的根结点到他们公共最近的结点距离,就OK了.不过这个题有个坑人的地方,不用输出那个空行,否则就是PE. 因为这个题询问比较

hdu 2874 Connections between cities hdu 2586 How far away ? LCA

两道lca模板题,用的是倍增法,nlogn预处理,logn查询. #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; #define maxn 10100 struct Edge { int u,v,w,next; }e[100100]; int n,m,c; int head[maxn],cnt; int fa[ma

HDU 2586 How far away ? &lt;&lt; LCA转RMQ+ST表 求树上任两点最短距离裸题

此题还有LCA+tarjin离线查询做法,详见这里 关于ST表 解决RMQ问题,dp[i][j]表示从第i位开始长度为(1<<j)的区间的最值 维护的时候采用倍增思想,维护dp[i][j+1]=opt(dp[i][j],dp[i+(1<<j)][j]) 查询的时候,两端点为l,r,则长度len=r-l,寻找一个k,使(1<<k)大于等于len/2,这样就使得 [l,l+(1<<k)]和[r-(1<<k),r]覆盖整个区间 然后此时,就可以直接用s

hdu 2586 How far away ?倍增LCA

hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增求取LCA,同时跟新距离数组 因为 \(2^{16} > 40000\) 所以所以表示祖先的数组dp[][]第二维取到16即可 就这道题来说,与比较tarjan比较,稍快一点 代码: #include <iostream> #include <algorithm> #includ

HDU - 2586 - How far away ?

先上题目: How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4936    Accepted Submission(s): 1866 Problem Description There are n houses in the village and some bidirectional roads conne

HDU 2586 How far away ? (离线LCA Tarjan算法模板)

How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6422    Accepted Submission(s): 2411 Problem Description There are n houses in the village and some bidirectional roads connecting

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house