最近公共祖先--lca
Posted wzq--boke
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最近公共祖先--lca相关的知识,希望对你有一定的参考价值。
模版题
https://www.luogu.org/problemnew/show/P3379
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<queue> 8 #define ll long long 9 using namespace std; 10 11 inline ll read(){ 12 ll x=0,f=1; char ch=getchar(); 13 for(;!isdigit(ch);ch=getchar())if(ch==‘-‘)f=-1; 14 for(;isdigit(ch);ch=getchar())x=ch-‘0‘+(x<<3)+(x<<1); 15 return x*f; 16 } 17 18 const int maxn=510000+1010; 19 int n,q,a[maxn],head[maxn],nx[maxn<<1],to[maxn<<1],tot; 20 21 inline void add(int x,int y){ 22 to[++tot]=y;nx[tot]=head[x];head[x]=tot; 23 to[++tot]=x;nx[tot]=head[y];head[y]=tot; 24 } 25 26 int dep[maxn],dp[maxn][21],f[maxn][21]; 27 void Deal(int u,int fa){ 28 dep[u]=dep[fa]+1; 29 for(int i=1;i<=20;i++){ 30 f[u][i]=f[f[u][i-1]][i-1]; 31 dp[u][i]=min(dp[u][i-1],dp[f[u][i-1]][i-1]); 32 } 33 for(int i=head[u];i;i=nx[i]){ 34 int k=to[i]; 35 if(k==fa)continue; 36 f[k][0]=u; 37 dp[k][0]=min(a[k],a[u]); 38 Deal(k,u); 39 } 40 } 41 42 int lca(int x,int y){ 43 int minn=min(a[x],a[y]); 44 if(dep[x]<dep[y])swap(x,y); 45 for(int i=20;i>=0;i--){ 46 if(dep[f[x][i]]>=dep[y]){ 47 minn=min(dp[x][i],minn); 48 x=f[x][i]; 49 } 50 if(x==y)return x; 51 } 52 for(int i=20;i>=0;i--){ 53 if(f[x][i]!=f[y][i]){ 54 minn=min(minn,min(dp[x][i],dp[y][i])); 55 x=f[x][i]; 56 y=f[y][i]; 57 } 58 } 59 return f[x][0]; 60 } 61 62 int s; 63 int main(){ 64 n=read();q=read(); 65 s=read(); 66 memset(dp,127,sizeof(dp)); 67 for(int i=1;i<n;i++){ 68 add(read(),read()); 69 } 70 Deal(s,0); 71 for(int i=1;i<=q;i++){ 72 printf("%d ",lca(read(),read())); 73 } 74 return 0; 75 }
严格次小生成树
https://www.luogu.org/problemnew/show/P4180
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<queue> 8 #define ll long long 9 using namespace std; 10 11 inline ll read(){ 12 ll x=0,f=1; char ch=getchar(); 13 for(;!isdigit(ch);ch=getchar())if(ch==‘-‘)f=-1; 14 for(;isdigit(ch);ch=getchar())x=ch-‘0‘+(x<<3)+(x<<1); 15 return x*f; 16 } 17 18 inline void write(ll n){ 19 char ch[24]; int top=0; 20 if(n==0){putchar(‘0‘);return ;} 21 if(n<0)putchar(‘-‘),n=-n; 22 while(n)ch[++top]=n%10+‘0‘,n/=10; 23 while(top)putchar(ch[top--]); 24 return ; 25 } 26 27 const int maxn=300000+1010; 28 const ll inf=21474836460000ll; 29 30 int n,m,tot,head[maxn],f[maxn]; 31 ll num; 32 bool book[maxn]; 33 34 struct wzq{int x,y,z;}a[maxn]; 35 struct hhh{int to,nx,v;}b[maxn<<1]; 36 37 inline void add(int x,int y,ll z){ 38 b[++tot].to=y;b[tot].nx=head[x];head[x]=tot;b[tot].v=z; 39 b[++tot].to=x;b[tot].nx=head[y];head[y]=tot;b[tot].v=z; 40 } 41 42 bool cmp(wzq i,wzq j){return i.z<j.z;} 43 44 int find(int x){if(f[x]==x)return x;return f[x]=find(f[x]);} 45 46 ll dep[maxn],fa[maxn][20],dp[maxn][20][2]; 47 void Deal(int u,int fe){ 48 dep[u]=dep[fe]+1; 49 for(int i=head[u];i;i=b[i].nx){ 50 ll k=b[i].to; 51 if(k==fe)continue; 52 dp[k][0][0]=-inf; 53 dp[k][0][1]=b[i].v; 54 fa[k][0]=u; 55 Deal(k,u); 56 } 57 } 58 59 inline void cal(){ 60 for(int i=1;i<=15;i++){ 61 for(int j=2;j<=n;j++){ 62 fa[j][i]=fa[fa[j][i-1]][i-1]; 63 dp[j][i][1]=max(dp[j][i-1][1],dp[fa[j][i-1]][i-1][1]); 64 if(dp[j][i-1][1]==dp[fa[j][i-1]][i-1][1])dp[j][i][0]=max(dp[j][i-1][0],dp[fa[j][i-1]][i-1][0]); 65 else if(dp[j][i-1][1]>dp[fa[j][i-1]][i-1][1])dp[j][i][0]=max(dp[j][i-1][0],dp[fa[j][i-1]][i-1][1]); 66 else if(dp[j][i-1][1]<dp[fa[j][i-1]][i-1][1])dp[j][i][0]=max(dp[j][i-1][1],dp[fa[j][i-1]][i-1][0]); 67 } 68 } 69 return ; 70 } 71 72 ll lca(int u,int q,int va){ 73 ll nnum=0; 74 if(dep[q]>dep[u])swap(q,u); 75 int gap=dep[u]-dep[q]; 76 for(int i=15;i>=0;i--){ 77 if(gap&(1<<i)){ 78 if(va>dp[u][i][1]){ 79 nnum=max(nnum,dp[u][i][1]); 80 } 81 else if(va==dp[u][i][1]){ 82 nnum=max(nnum,dp[u][i][0]); 83 } 84 u=fa[u][i]; 85 } 86 } 87 for(int i=15;i>=0;i--){ 88 if(fa[u][i]!=fa[q][i]){ 89 if(va>dp[u][i][1]){ 90 nnum=max(nnum,dp[u][i][1]); 91 } 92 else if(va==dp[u][i][1]){ 93 nnum=max(nnum,dp[u][i][0]); 94 } 95 if(va>dp[q][i][1]){ 96 nnum=max(nnum,dp[q][i][1]); 97 } 98 else if(va==dp[q][i][1]){ 99 nnum=max(nnum,dp[q][i][0]); 100 } 101 u=fa[u][i]; 102 q=fa[q][i]; 103 } 104 } 105 if(va>dp[u][0][1]){ 106 nnum=max(nnum,dp[u][0][1]); 107 } 108 if(va>dp[q][0][1]){ 109 nnum=max(nnum,dp[q][0][1]); 110 } 111 return nnum; 112 113 } 114 115 116 117 int main(){ 118 119 n=read();m=read(); 120 for(int i=1;i<=n;i++)f[i]=i; 121 for(int i=1;i<=m;i++){a[i].x=read();a[i].y=read();a[i].z=read();} 122 123 sort(a+1,a+m+1,cmp); 124 for(int i=1;i<=m;i++){ 125 int x1=find(f[a[i].x]),y1=find(f[a[i].y]); 126 if(x1!=y1){ 127 f[x1]=y1; 128 num+=a[i].z; 129 add(a[i].x,a[i].y,a[i].z); 130 book[i]=true; 131 } 132 } 133 134 Deal(1,0); 135 cal(); 136 137 ll nnum=inf; 138 for(int i=1;i<=m;i++){ 139 if(book[i])continue; 140 ll maxx=lca(a[i].x,a[i].y,a[i].z); 141 nnum=min(nnum,num-maxx+a[i].z); 142 } 143 write(nnum); 144 return 0; 145 }
以上是关于最近公共祖先--lca的主要内容,如果未能解决你的问题,请参考以下文章