`
Simone_chou
  • 浏览: 192506 次
  • 性别: Icon_minigender_2
  • 来自: 广州
社区版块
存档分类
最新评论

Distance Queries(LCA 在线算法 RMQ)

    博客分类:
  • POJ
 
阅读更多
Distance Queries
Time Limit: 2000MS   Memory Limit: 30000K
Total Submissions: 9500   Accepted: 3332
Case Time Limit: 1000MS

Description

Farmer John's cows refused to run in his marathon since he chose a path much too long for their leisurely lifestyle. He therefore wants to find a path of a more reasonable length. The input to this problem consists of the same input as in "Navigation Nightmare",followed by a line containing a single integer K, followed by K "distance queries". Each distance query is a line of input containing two integers, giving the numbers of two farms between which FJ is interested in computing distance (measured in the length of the roads along the path between the two farms). Please answer FJ's distance queries as quickly as possible! 

Input

* Lines 1..1+M: Same format as "Navigation Nightmare" 

* Line 2+M: A single integer, K. 1 <= K <= 10,000 

* Lines 3+M..2+M+K: Each line corresponds to a distance query and contains the indices of two farms. 

Output

* Lines 1..K: For each distance query, output on a single line an integer giving the appropriate distance. 

Sample Input

7 6
1 6 13 E
6 3 9 E
3 5 7 S
4 1 3 N
2 4 20 W
4 7 2 S
3
1 6
1 4
2 6

Sample Output

13
3
36

Hint

Farms 2 and 6 are 20+3+13=36 apart. 
 

     题意:

     给出 N 和 M,代表 N 个节点,M 条边,后给出边信息,有 K 个询问,输出每个询问两点间的距离。

 

     思路:

     LCA。RMQ 的在线算法。

 

     AC:

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int VMAX = 40010;
const int EMAX = VMAX * 5;

int ind;
int v[EMAX], fir[VMAX], next[EMAX], w[EMAX];

int ans;
int id[VMAX], vs[VMAX * 2], dep[VMAX * 2], dis[VMAX];
bool vis[VMAX];

int dp[VMAX * 2][30];

void init () {
    ind = ans = 0;
    memset(fir, -1, sizeof(fir));
    memset(vis, 0, sizeof(vis));
}

void add_edge (int f, int t, int val) {
    v[ind] = t;
    w[ind] = val;
    next[ind] = fir[f];
    fir[f] = ind;
    ++ind;
}

void dfs (int x, int d) {
    vis[x] = 1;
    id[x] = ans;
    dep[ans] = d;
    vs[ans++] = x;

    for (int e = fir[x]; e != -1; e = next[e]) {
        int V = v[e];
        if (!vis[V]) {
            dis[V] = dis[x] + w[e];
            dfs(V, d + 1);
            dep[ans] = d;
            vs[ans++] = x;
        }
    }
}

void RMQ_init () {
    for (int i = 0; i < ans; ++i) dp[i][0] = i;

    for (int j = 1; (1 << j) <= ans; ++j) {
        for (int i = 0; i + (1 << j) < ans; ++i) {
            int a = dp[i][j - 1];
            int b = dp[i + (1 << (j - 1))][j - 1];
            if (dep[a] < dep[b]) dp[i][j] = a;
            else dp[i][j] = b;
        }
    }
}

int RMQ (int L, int R) {
    int len = 0;
    while ((1 << (len + 1)) <= (R - L + 1)) ++len;

    int a = dp[L][len];
    int b = dp[R - (1 << len) + 1][len];

    if (dep[a] < dep[b]) return a;
    return b;
}

int LCA (int a, int b) {
    int L = min(id[a], id[b]);
    int R = max(id[a], id[b]);

    int node = RMQ(L, R);
    return vs[node];
}

int main () {

    init();

    int n, m;
    scanf("%d%d", &n, &m);

    while (m--) {
        int a, b, val;
        char c;
        scanf("%d%d%d %c", &a, &b, &val, &c);
        add_edge(a, b, val);
        add_edge(b, a, val);
    }

    dis[1] = 0;
    dfs(1, 1);

    RMQ_init();

    int k;
    scanf("%d", &k);
    while (k--) {
        int a, b;
        scanf("%d%d", &a, &b);

        int c = LCA(a, b);
        printf("%d\n", dis[a] + dis[b] - 2 * dis[c]);
    }

    return 0;
}

 

 

分享到:
评论

相关推荐

    LCA RMQ 最小公共祖先 区间最小值

    LCA(Lowest Common Ancestor)和 RMQ(Range Minimum Query)是两种常见的数据结构算法问题。LCA 问题的目的是在一棵树中找到两个结点的最近公共祖先,而 RMQ 问题的目的是在一个数组中找到两个索引之间的最小值的...

    算法之LCA与RMQ问题1

    为了提高效率,可以采用在线算法如DFS+ST(深度优先搜索+稀疏表)或离线算法如Tarjan算法。DFS+ST方法通过深度优先遍历构建E数组,并计算R数组以确定访问顺序,从而在O(logn)时间内找到LCA。Tarjan算法则是通过松弛...

    RMQ和LCA详解

    关于RMQ和LCA的关系的知识,如何用RMQ和LCA的转换

    lca-rmq:RMQ查找LCA的算法的实现

    最小公祖问题的算法。 如“重新审阅LCA问题”中所述,这将使用“范围最小查询”实现LCA。 已完成:天真RMQ,更快RMQ(使用nlogn稀疏表) 待办事项:执行±1 RMQ 天真的RMQ输出: (1(2(4..)(5..))(3(6..)(7..)))...

    LCA问题归约成RMQ求解

    在计算机科学领域,特别是数据结构和算法分析中,"LCA问题归约成RMQ求解"是一个重要的主题。LCA代表最远公共祖先(Least Common Ancestor),而RMQ代表范围最小值查询(Range Minimum Query)。这两个概念常用于树形...

    LCA与RMQ相关题解1

    【LCA(最近公共祖先)】 最近公共祖先(Lowest ...总的来说,LCA和RMQ都是数据结构和算法中的经典问题,它们在处理树形结构和数组区间查询时有着广泛的应用。掌握这些方法,对于解决类似问题能提供高效的解决方案。

    Tarjan 的 LCA 算法

    **Tarjan的LCA算法详解** 最近公共祖先(Lowest Common Ancestor,简称LCA)是图论中的一个重要概念,特别是在树形结构中。在树中,两个节点的最近公共祖先指的是距离根节点最近的那个同时是这两个节点的祖先的节点...

    RMQ与LCA问题

    算法学习

    RMQ与LCA ACM必备

    RMQ分为在线算法和离线算法。 1. **在线算法**: 在线算法需要在接收到查询时立即给出答案。预处理阶段可能需要较长时间,但之后每次回答查询的速度非常快。例如,简单的动态规划方法虽然能实现O(1)的查询时间,但...

    打萎的RMQ 和 LCA

    LCA的解法有多种,其中Tarjan算法是一个在线处理算法,适合动态树的场景,时间复杂度为O(nlogn)。另一个广泛应用的算法是离线处理的算法,通常利用RMQ算法的思路来解决LCA问题。具体方法是先通过深度优先遍历(DFS)...

    郭华阳《RMQ与LCA问题》

    **RMQ(Range Minimum Query)与LCA(Lowest Common Ancestor)问题**是图论与数据结构领域中的两个重要概念,广泛应用于算法设计和优化。这篇由郭华阳所著的国家队论文深入探讨了这两个问题及其解决方案。 **RMQ...

    RMQ&LCA;问题

    该ppt讲了一种基于线段树的RMQ的ST算法问题和LCA算法,适合初学者用。

    Pascal LCA 倍增法详解及代码

    解决LCA问题的方法主要有两类:在线算法和离线算法。在线算法需要在每次询问时快速回答,而离线算法则先一次性处理所有询问。朴素的在线算法时间复杂度较高,可达O(n),在大量询问的情况下效率较低。 本文介绍的是...

    算法合集之RMQ与LCA问题PPT学习教案.pptx

    RMQ(Range Minimum Query,区间最小值查询)与LCA(Lowest Common Ancestor,最近公共祖先)是两种常见的算法问题,广泛应用于数据结构、图论以及计算机科学竞赛中。 RMQ问题通常涉及到在一个给定的线性序列A中,...

    ACM中的RMQ和LCA问题

    对于RMQ的求解,有两种主要的方法:在线算法和离线算法。 在线算法在预处理阶段花费较长的时间,但之后每次回答查询只需较少的时间。例如,动态规划方法虽然能直接求解,但效率较低,预处理时间复杂度为O(n^2),...

    3.郭华阳《RMQ与LCA问题》1

    这个问题在数据结构和算法中具有广泛的应用,特别是在动态规划和在线算法的设计中。 LCA(Lowest Common Ancestor)问题则是针对树形结构的一个经典问题,它要求找出树中两个节点的最近公共祖先。最近公共祖先指的...

    算法文档无代码RMQ&LCA问题

    算法文档无代码RMQ&LCA问题提取方式是百度网盘分享地址

Global site tag (gtag.js) - Google Analytics