RMQ转换LCA模板 ST算法

原理:

void dfs(int k,int d,long long sum)
{
    cost[k]=sum;
    pos[k]=++tot; ///记录第一次出现的时间戳
    F[tot]=k; ///记录欧拉序列
    rmq[tot]=d;///记录该时间戳深度
    vis[k]=1;
    for(int i=fir[k];~i;i=nex[i])
    {
        int e=v[i];
        if(!vis[e])
        {
            dfs(e,d+1,sum+w[i]);
            F[++tot]=k; ///继续记录访问时间戳,那么此时就相当于在每个子节点中插入了父节点,
                        ///在利用pos下标查询RMQ时父节点的信息就卡在了两者之间
            rmq[tot]=d;
        }
    }
}

ST(来源 :kuangbin模板):

int F[maxn],pos[maxn],tot;
long long cost[maxn];

int rmq[maxn];//rmq数组,就是欧拉序列对应的深度序列
struct ST
{
    int mm[2*maxn];
    int dp[2*maxn][20];//最小值对应的下标
    void init(int n)
    {
        mm[0] = -1;
        for(int i = 1; i <= n; i++)
        {
            mm[i] = ((i&(i-1)) == 0)?mm[i-1]+1:mm[i-1];
            dp[i][0] = i;
        }
        for(int j = 1; j <= mm[n]; j++)
            for(int i = 1; i + (1< b)swap(a,b);
        int k = mm[b-a+1];
        return rmq[dp[a][k]] <= rmq[dp[b-(1<

初始化:

void LCA_init()
{
    memset(vis,0,sizeof vis);
    for(int i=1; i<=n; i++)
    {
        if(!vis[i])
        {
            dfs(i,1,0);
        }
    }
    st.init(tot);
}


查询部分:

long long Query(int s,int t)
{
    int lca=F[ st.query(pos[s],pos[t]) ];
    return cost[s]+cost[t]-2*cost[lca];
}

HDU 2586  How far away ?


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#pragma comment(linker, "/STACK:1024000000,1024000000");

using namespace std;

#define INF 0x3f3f3f3f
#define maxn 80004

int fir[maxn],nex[maxn],v[maxn],w[maxn],e_max;
int pos[2*maxn],T[2*maxn],tot;
long long cost[maxn];
int rmq[2*maxn];//rmq数组,就是欧拉序列对应的深度序列
struct ST
{
    int mm[2*maxn];
    int dp[2*maxn][20];//最小值对应的下标
    void init(int n)
    {
        mm[0] = -1;
        for(int i = 1; i <= n; i++)
        {
            mm[i] = ((i&(i-1)) == 0)?mm[i-1]+1:mm[i-1];
            dp[i][0] = i;
        }
        for(int j = 1; j <= mm[n]; j++)
            for(int i = 1; i + (1< b)swap(a,b);
        int k = mm[b-a+1];
        return rmq[dp[a][k]] <= rmq[dp[b-(1<

POJ 1986 Distance Queries

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#pragma comment(linker, "/STACK:1024000000,1024000000");

using namespace std;

#define INF 0x3f3f3f3f
#define maxn 80004

int x[maxn],y[maxn],c[maxn],e[maxn],s[maxn],pos[2*maxn];
int fir[maxn],nex[maxn],v[maxn],w[maxn],e_max,tot;
long long cost[maxn];

int rmq[2*maxn],F[2*maxn];//rmq数组,就是欧拉序列对应的深度序列
struct ST
{
    int mm[2*maxn];
    int dp[2*maxn][20];//最小值对应的下标
    void init(int n)
    {
        mm[0] = -1;
        for(int i = 1; i <= n; i++)
        {
            mm[i] = ((i&(i-1)) == 0)?mm[i-1]+1:mm[i-1];
            dp[i][0] = i;
        }
        for(int j = 1; j <= mm[n]; j++)
            for(int i = 1; i + (1< b) swap(a,b);
        int k = mm[b-a+1];
        return rmq[dp[a][k]] <= rmq[dp[b-(1<


HDU 2874 Connections between cities


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#pragma comment(linker, "/STACK:1024000000,1024000000");

using namespace std;

#define INF 0x3f3f3f3f
#define maxn 40004

int x[maxn],y[maxn],c[maxn],e[maxn];
int vis[maxn];
int fir[maxn],nex[maxn],v[maxn],w[maxn],e_max,s[maxn];
int F[maxn],pos[maxn],tot;
long long cost[maxn];

int rmq[maxn];//rmq数组,就是欧拉序列对应的深度序列
struct ST
{
    int mm[2*maxn];
    int dp[2*maxn][20];//最小值对应的下标
    void init(int n)
    {
        mm[0] = -1;
        for(int i = 1; i <= n; i++)
        {
            mm[i] = ((i&(i-1)) == 0)?mm[i-1]+1:mm[i-1];
            dp[i][0] = i;
        }
        for(int j = 1; j <= mm[n]; j++)
            for(int i = 1; i + (1< b)swap(a,b);
        int k = mm[b-a+1];
        return rmq[dp[a][k]] <= rmq[dp[b-(1<

你可能感兴趣的:(===图论===,LCA)