HDU 2586(LCA欧拉序和st表)
Posted luoyugongxi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 2586(LCA欧拉序和st表)相关的知识,希望对你有一定的参考价值。
什么是欧拉序,可以去这个大佬的博客(https://www.cnblogs.com/stxy-ferryman/p/7741970.html)巨详细
因为欧拉序中的两点之间,就是两点遍历的过程,所以只要找遍历过程中对应的最小的深度就行了,这里用st表存,first存第一个u出现的地方,用value存欧拉序,同时用depth存对应深度
模板
1 struct node{ 2 int v,next,dist; 3 }a[maxn<<1]; 4 int n,m,tot,len; 5 int st[maxn<<1][20], depth[maxn<<1],value[maxn<<1],first[maxn<<1]; 6 int dist[maxn],head[maxn]; 7 void add(int u,int v,int dist0){ 8 a[tot].next=head[u]; 9 a[tot].dist=dist0; 10 a[tot].v=v; 11 head[u]=tot++; 12 } 13 void dfs(int u,int fa,int d) { 14 value[++len]=u;depth[len]=d;first[u]=len; 15 for (int i=head[u];~i;i=a[i].next){ 16 int v=a[i].v;if(v==fa)continue; 17 dist[v]=dist[u]+a[i].dist; 18 dfs(v,u,d+1); 19 value[++len]=u;depth[len]=d; 20 } 21 } 22 inline void init(int n){ 23 for(int i=0;i<=n;i++)head[i]=-1,depth[i]=0; 24 tot=0,len=0; 25 } 26 inline void makest(){ 27 for(it i=1;i<=len;i++)st[i][0]=depth[i]; 28 for(it i=1;1<<i<=len;i++){ 29 for(it j=1;j+(1<<i)-1<=len;j++){ 30 st[j][i]=min(st[j][i-1],st[j+(1<<(i-1))][i-1]); 31 } 32 } 33 } 34 inline int dis(int u,int v){ 35 int l=first[u],r=first[v]; 36 if(l>r){swap(l,r);} 37 int k=log2(r-l+1); 38 int dep=min(st[l][k],st[r-(1<<k)+1][k]); 39 return dist[u]+dist[v]-2*dist[value[first[dep]]]; 40 }
题意:
以1为根的树,两个点之间的最近距离是多少
思路:
模板LCA
用欧拉序+st表
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define il inline 5 #define it register int 6 #define inf 0x3f3f3f3f 7 #define lowbit(x) (x)&(-x) 8 #define mem(a,b) memset(a,b,sizeof(a)) 9 #define modd 998244353 10 const int maxn=4e4+10; 11 struct node{ 12 int v,next,dist; 13 }a[maxn<<1]; 14 int n,m,tot,len; 15 int st[maxn<<1][20], depth[maxn<<1],value[maxn<<1],first[maxn<<1]; 16 int dist[maxn],head[maxn]; 17 void add(int u,int v,int dist0){ 18 a[tot].next=head[u]; 19 a[tot].dist=dist0; 20 a[tot].v=v; 21 head[u]=tot++; 22 } 23 void dfs(int u,int fa,int d) { 24 value[++len]=u;depth[len]=d;first[u]=len; 25 for (int i=head[u];~i;i=a[i].next){ 26 int v=a[i].v;if(v==fa)continue; 27 dist[v]=dist[u]+a[i].dist; 28 dfs(v,u,d+1); 29 value[++len]=u;depth[len]=d; 30 } 31 } 32 inline void init(int n){ 33 for(int i=0;i<=n;i++)head[i]=-1,depth[i]=0; 34 tot=0,len=0; 35 } 36 inline void makest(){ 37 for(it i=1;i<=len;i++)st[i][0]=depth[i]; 38 for(it i=1;1<<i<=len;i++){ 39 for(it j=1;j+(1<<i)-1<=len;j++){ 40 st[j][i]=min(st[j][i-1],st[j+(1<<(i-1))][i-1]); 41 } 42 } 43 } 44 inline int dis(int u,int v){ 45 int l=first[u],r=first[v]; 46 if(l>r){swap(l,r);} 47 int k=log2(r-l+1); 48 int dep=min(st[l][k],st[r-(1<<k)+1][k]); 49 return dist[u]+dist[v]-2*dist[value[first[dep]]]; 50 } 51 int main(){ 52 int t; 53 scanf("%d",&t); 54 while(t--){ 55 scanf("%d%d",&n,&m); 56 init(n); 57 for(it i=0;i<n-1;i++){int u,v,w; 58 scanf("%d%d%d",&u,&v,&w); 59 add(u,v,w);add(v,u,w); 60 } 61 dfs(1,0,1); 62 makest(); 63 while(m--){ 64 int l,r; 65 scanf("%d%d",&l,&r); 66 printf("%d ",dis(l,r)); 67 } 68 } 69 return 0; 70 }
用倍增
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define il inline 5 #define it register int 6 #define inf 0x3f3f3f3f 7 #define lowbit(x) (x)&(-x) 8 #define mem(a,b) memset(a,b,sizeof(a)) 9 #define modd 998244353 10 const int maxn=4e4+10; 11 struct node{ 12 int v,next,dist; 13 }a[maxn<<1]; 14 int n,m,tot; 15 int fath[maxn][20], depth[maxn]; 16 int dist[maxn],head[maxn]; 17 void add(int u,int v,int dist0){ 18 a[tot].next=head[u]; 19 a[tot].dist=dist0; 20 a[tot].v=v; 21 head[u]=tot++; 22 } 23 void dfs(int u,int fa,int d) { 24 fath[u][0]=fa; depth[u]=d; 25 for(int i=1;i<20;i++) fath[u][i]=fath[fath[u][i-1]][i-1]; 26 for (int i=head[u];~i;i=a[i].next){ 27 int v=a[i].v;if(v==fa)continue; 28 dist[v]=dist[u]+a[i].dist; 29 dfs(v,u,d+1); 30 } 31 } 32 void init(int n){ 33 for(int i=0;i<=n;i++)fath[i][0]=0,dist[i]=0,head[i]=-1,depth[i]=0; 34 tot=0; 35 } 36 inline int lca(int x,int y){ 37 if(depth[x]<depth[y])swap(x,y); 38 int h=depth[x]-depth[y]; 39 for(it i=0;h>0;i++){ 40 if(h&1){ 41 x=fath[x][i]; 42 } 43 h>>=1; 44 } 45 if(x==y)return x; 46 for(it i=19;i>=0;i--){ 47 if(fath[x][i]!=fath[y][i]){ 48 x=fath[x][i]; 49 y=fath[y][i]; 50 } 51 } 52 return fath[x][0]; 53 } 54 inline int dis(int u,int v){ 55 int d=lca(u,v); 56 return dist[u]+dist[v]-2*dist[d]; 57 } 58 int main(){ 59 int t; 60 scanf("%d",&t); 61 while(t--){ 62 scanf("%d%d",&n,&m); 63 init(n); 64 for(it i=0;i<n-1;i++){int u,v,w; 65 scanf("%d%d%d",&u,&v,&w); 66 add(u,v,w);add(v,u,w); 67 } 68 dfs(1,0,1); 69 while(m--){ 70 int l,r; 71 scanf("%d%d",&l,&r); 72 printf("%d ",dis(l,r)); 73 } 74 } 75 return 0; 76 }
以上是关于HDU 2586(LCA欧拉序和st表)的主要内容,如果未能解决你的问题,请参考以下文章
HDU - 2586 How far away? 在线LCA ST算法