SP3978 DISQUERY - Distance Query
Posted qyj060604
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SP3978 DISQUERY - Distance Query相关的知识,希望对你有一定的参考价值。
SP3978 DISQUERY - Distance Query
LCA高级水题
倍增搞一搞即可
代码:
#include<bits/stdc++.h> using namespace std; const int N=100005; int n,m; int hed[N<<1],tal[N<<1],val[N<<1],nxt[N<<1],cnt=0; int Start[N],End[N]; int dep[N]={0}; int f[N][30]; int maxn[N][30]; int minn[N][30]; void addege(int x,int y,int z){ cnt++; tal[cnt]=y; val[cnt]=z; nxt[cnt]=hed[x]; hed[x]=cnt; } void dfs(int u,int father){ f[u][0]=father; for(int i=hed[u];i;i=nxt[i]){ int v=tal[i]; if(v==father) continue; dep[v]=dep[u]+1; maxn[v][0]=val[i]; minn[v][0]=val[i]; dfs(v,u); } } int LCA1(int u,int v){ int ans=2147483647; if(dep[u]<dep[v]) swap(u,v); for(int i=28;i>=0;i--) if(dep[f[u][i]]>=dep[v]) ans=min(ans,minn[u][i]),u=f[u][i]; if(u==v) return ans; for(int i=28;i>=0;i--) if(f[u][i]!=f[v][i]) ans=min(ans,minn[u][i]),ans=min(ans,minn[v][i]),u=f[u][i],v=f[v][i]; ans=min(ans,min(minn[u][0],minn[v][0])); return ans; } int LCA2(int u,int v){ int ans=-2147483647; if(dep[u]<dep[v]) swap(u,v); for(int i=28;i>=0;i--) if(dep[f[u][i]]>=dep[v]) ans=max(ans,maxn[u][i]),u=f[u][i]; if(u==v) return ans; for(int i=28;i>=0;i--) if(f[u][i]!=f[v][i]) ans=max(ans,maxn[u][i]),ans=max(ans,maxn[v][i]),u=f[u][i],v=f[v][i]; ans=max(ans,max(maxn[u][0],maxn[v][0])); return ans; } int main(){ memset(minn,127,sizeof(minn)); memset(maxn,128,sizeof(maxn)); scanf("%d",&n); for(int i=1;i<n;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); addege(x,y,z); addege(y,x,z); } dep[1]=1; dfs(1,1); for(int j=1;j<=28;j++){ for(int i=1;i<=n;i++){ f[i][j]=f[f[i][j-1]][j-1]; maxn[i][j]=max(maxn[i][j-1],maxn[f[i][j-1]][j-1]); minn[i][j]=min(minn[i][j-1],minn[f[i][j-1]][j-1]); } } scanf("%d",&m); while(m--){ int u,v; scanf("%d%d",&u,&v); printf("%d %d ",LCA1(u,v),LCA2(u,v)); } return 0; }
以上是关于SP3978 DISQUERY - Distance Query的主要内容,如果未能解决你的问题,请参考以下文章