LCA问题

LCA的求解有3种,转化为RMQ,Tarjan离线预处理,倍增法。

RMQ法:

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <set>
#include <cmath>
#include <cstring>

#define LL long long
using namespace std;
struct node
{
    int p, v;
};
const LL N = 100005;
vector<node> g[N];
LL fst[N];
LL ver[N * 2];
LL deep[N * 2];
LL dist[N];
LL pos;
int vis[N];
int n, m;
LL lg2(LL nu)
{
    return log10(nu) / log10(2);
}
void dfs(int now, int dep, int dis)
{
    ver[pos] = now;
    fst[now] = pos;
    deep[pos++] = dep;
    dist[now] = dis;
    vis[now] = 1;
    for (int i = 0; i < g[now].size(); i++)
    {
        if (!vis[g[now][i].p])
        {
            dfs(g[now][i].p, dep + 1, dis + g[now][i].v);
            ver[pos] = now;
            deep[pos++] = dep;
        }
    }
}
LL dp[N * 2][25];
LL bit[25];
void initRMQ()
{
    int bitlen = lg2(2 * n - 1);
    bit[0] = 1;
    for (int i = 1; i <= bitlen; i++) bit[i] = bit[i - 1] * 2;
    for (int i = 0; i <pos; i++)
        dp[i][0] = ver[i];
    for (int j = 1; j <= bitlen; j++)
    {
        for (int i = 0; i + bit[j] < pos; i++)
        {
            int lx = dp[i][j - 1], rx = dp[i + bit[j - 1]][j - 1];
            dp[i][j] = deep[fst[lx]] < deep[fst[rx]] ? lx : rx;
        }
    }
}
int query(int a, int b)
{
    if (a == b) return a;
    a = fst[a], b = fst[b];
    if (a > b) swap(a, b);
    int kk = lg2(b - a + 1);
    int lx = dp[a][kk], rx = dp[b - bit[kk] + 1][kk];
    return deep[fst[lx]] < deep[fst[rx]] ? lx : rx;
}
int getDis(int a, int b)
{
    int p = query(a, b);
    return dist[a] + dist[b] - 2 * dist[p];
}

 

posted @ 2017-07-29 10:30  Luke_Ye  阅读(231)  评论(0编辑  收藏  举报