原理:
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;
}
}
}
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
POJ 1986 Distance Queries
#include
#include
#include
#include
#include
#include
#include
HDU 2874 Connections between cities
#include
#include
#include
#include
#include
#include
#include