RMQ实现LCA

原创 2012年03月30日 21:50:31

RMQ实现LCA。。。。。。。。。。弄了一下午,终于搞定了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<climits>
using namespace std;

const int N = 100005; //不同结点数
const int M = N * 2; //总结点数
int visit[M], level[M], first[N];
int q[20][N];
int num;

struct Node
{
    int father;
    vector<int> son;
    Node()
    {
        father = -1;
        son.clear();
    }
}node[N];

void DFS(int cur, int now)
{
     if(first[now] == -1)
        first[now] = num;
    level[num] = cur;
    visit[num++] = now;

    if(node[now].son.size() == 0) //终止条件
        return ;

    for(vector<int>::iterator i = node[now].son.begin(); i != node[now].son.end(); ++i)
        {
            DFS(cur + 1, *i);
            visit[num] = now;
            level[num++] = cur;
        }
}

void RMQ(int n)
{
    for(int i = 1; i <= n; ++i)
        q[0][i] = level[i];
    for(int i = 1; i != 20; ++i)
        for(int j = 1; j <= n; ++j)
            if(j + (1 << i) - 1 <= n)
                q[i][j] = min(q[i - 1][j], q[i - 1][j + (1 << i >> 1)]);
}

int main()
{
    int vnum, edge, query;
    int a, b;
    int start, end;
    while(scanf("%d %d %d", &vnum, &edge, &query) != EOF)
    {
        memset(first, -1, sizeof(first));
        num = 1;
        for(int i = 0; i < edge; ++i)
        {
            scanf("%d %d", &a, &b);
            node[a].son.push_back(b);
            node[b].father = a;
        }
        DFS(0, 1);
        RMQ(num - 1);
        while(query--)
        {
            scanf("%d %d", &start, &end);
        start = first[start], end = first[end];
        if(start > end)
            swap(start, end);
        int k = (int)(log(end - start + 1.0) / log(2.0));
        int res = min(q[k][start], q[k][end - (1 << k) + 1]);
        int ans;
        for(int i = start; i <= end; ++i)
            if(level[i] == res)
            {
                ans = i;
                break;
            }
        printf("%d\n", visit[ans]);
        }
    }
    return 0;
}


LCA和RMQ的一些事情(最近公共祖先与区间最值查询)

原创戳这里 本来想详细写写LCA和RMQ的东西的,但是觉得积累得还不够而且比较懒就不写了。鉴于都是超经典问题,网上和大量书籍都是很好的学习材料,所以就不想说了 这里只简单说说原理,说说代码实现上面的...
  • qq_35653247
  • qq_35653247
  • 2016年08月26日 19:37
  • 940

LCA 转 RMQ算法 【总结】

首先,在你看这个算法之前,要确保你理解了RMQ的 ST 算法。 但是不理解没关系啊,提供通道:  点我 声明:这是方便我以后复习用的,所以总结不是特别详细。 LCA - 最近公共祖先:在有根树...
  • chenzhenyu123456
  • chenzhenyu123456
  • 2015年08月08日 18:48
  • 1460

转+原:RMQ与LCA(From TopCoder Algorithm Tutorials)

原帖地址:http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAncestor#Range_Minimum_Que...
  • hell2pradise
  • hell2pradise
  • 2010年08月16日 16:01
  • 4887

LCA转RMQ 模版及解析 + LCA倍增法模版

九野的博客,转载请注明出处:http://blog.csdn.net/acmmmm/article/details/15490519   LCA:  最近公共祖先 则 LCA(2,3) = 2 ;...
  • qq574857122
  • qq574857122
  • 2013年11月11日 23:21
  • 4068

A - 春の湊に舟の影 HDU - 2586 LCA/RMQ模板

//#include //#pragma comment(linker, "/STACK:1024000000,1024000000") #include #include #include #in...
  • qq_34927456
  • qq_34927456
  • 2017年07月17日 11:43
  • 127

最近公共祖先(LCA)算法实现过程 【Tarjan离线+倍增在线+RMQ】

最近公共祖先(LCA) 首先来介绍下最近公共祖先(LCA)的概念 百度上的解释:对于有根树T的两个结点u、v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u、v的祖先且x的深度...
  • my_sunshine26
  • my_sunshine26
  • 2017年05月24日 22:31
  • 1234

POJ 2763 Housewife Wind LCA转RMQ+时间戳+线段树成段更新

题目来源:POJ 2763 Housewife Wind 题意:给你一棵树 2种操作0 x 求当前点到x的最短路 然后当前的位置为x; 1 i x 将第i条边的权值置为x 思路:树上两点u, v距离为...
  • u011686226
  • u011686226
  • 2014年07月15日 23:03
  • 1063

LCA转RMQ 在线算法模板

hdu 2586 #include #include #include #include #include #include #include #include #include ...
  • u014451076
  • u014451076
  • 2015年08月16日 11:02
  • 320

rmq问题和lca可以相互转化

Sparse Table算法 一般RMQ的Sparse Table(ST)算法是基于倍增思想设计的O(Nlog2N) – O(1)在线算法 算法记录从每个元素开始的连续的长度为2k的区...
  • u011483306
  • u011483306
  • 2014年05月02日 17:20
  • 398

RMQ转换LCA模板 ST算法

原理: void dfs(int k,int d,long long sum) { cost[k]=sum; pos[k]=++tot; ///记录第一次出现的时间戳 F[to...
  • Forever_wjs
  • Forever_wjs
  • 2016年08月09日 10:23
  • 412
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:RMQ实现LCA
举报原因:
原因补充:

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