hdu2586 lca模板(在线RMQ)
杭电这题在线rmq用C++交会RE,G++才能过,但是手动开个栈C++就能AC了。。
在线RMQ用的一种倍增思想,还是很常见的,必然要熟练运用
数组具体功能代码里面都有:
dis[N] 距离根节点距离
id[N] 节点映射到dfs时间序上
doit[X] 时间点对应的原节点
depth[X] 该时间点深度
RMQ中:evalue[x][j] 于x起点2^j长度深度最小值 epoint[x][j] 于x起点2^j长度深度最小值时的节点
基于RMQ的在线lca思想:一遍dfs时间戳上述几个数组,然后利用RMQ预处理==
1 #pragma comment(linker,"/STACK:16777216") 2 #include<stdio.h> 3 #include<string.h> 4 #include<algorithm> 5 using namespace std; 6 int now,time_,head[100005],next[100005],point[100005],value[100005]; 7 int dis[100005],id[100005],doit[100005],depth[100005]; 8 //距离根节点距离,映射到dfs序上的时间,这个时间的原节点,该时间深度 9 void add(int x,int y,int z) 10 { 11 next[++now]=head[x]; 12 head[x]=now; 13 point[now]=y; 14 value[now]=z; 15 } 16 void dfs(int u,int pre,int deep,int d) 17 { 18 dis[u]=d; 19 id[u]=++time_; 20 doit[time_]=u; 21 depth[time_]=deep; 22 for (int i=head[u];i;i=next[i]) 23 { 24 int v=point[i],w=value[i]; 25 if (v==pre) continue; 26 dfs(v,u,deep+1,d+w); 27 doit[++time_]=u; 28 depth[time_]=deep; 29 } 30 } 31 int epoint[100005][20],evalue[100005][20]; 32 void rmq_build(int x) 33 { 34 int i,j; 35 for (i=1;i<=x;i++) 36 { 37 epoint[i][0]=doit[i];//为了返回最小值对应原树中下标 38 evalue[i][0]=depth[i];//为了找出在处理时间序内的深度最小 39 } 40 for (j=1;(1<<j)<=x;j++) 41 for (i=1;i+(1<<j)-1<=x;i++) 42 { 43 evalue[i][j]=min(evalue[i][j-1],evalue[i+(1<<(j-1))][j-1]); 44 epoint[i][j]=evalue[i][j-1]<evalue[i+(1<<(j-1))][j-1]? 45 epoint[i][j-1]:epoint[i+(1<<(j-1))][j-1]; 46 } 47 } 48 int rmq_query(int l,int r) 49 { 50 int k=0; 51 while ((1<<(k+1))<=r-l+1) k++; 52 return evalue[l][k]<evalue[r-(1<<k)+1][k]? 53 epoint[l][k]:epoint[r-(1<<k)+1][k]; 54 } 55 int main() 56 { 57 int T,m,x,y,z,i,n; 58 scanf("%d",&T); 59 while (T--) 60 { 61 scanf("%d%d",&n,&m); 62 now=time_=0; 63 memset(head,0,sizeof(head)); 64 for (i=1;i<n;i++) 65 { 66 scanf("%d%d%d",&x,&y,&z); 67 add(x,y,z); add(y,x,z); 68 } 69 dfs(1,-1,1,0); 70 rmq_build(2*n-1); 71 while (m--) 72 { 73 scanf("%d%d",&x,&y); 74 z=rmq_query(min(id[x],id[y]),max(id[x],id[y])); 75 //转化为工作时间序进入rmq 76 printf("%d\n",dis[x]+dis[y]-2*dis[z]);//距离计算 77 } 78 } 79 return 0; 80 }