LCA

xiaoxiao2021-02-28  85

#include <iostream> #include<algorithm> #include<stdio.h> #include<string.h> #include<cmath> using namespace std; const int maxn=40010; struct node { int to,next,w; }edge[maxn<<1]; int head[maxn],cnt; void addedge(int u,int v,int we) { edge[cnt].to=v ; edge[cnt].next=head[u]; edge[cnt].w=we; head[u]=cnt++; } bool vis[maxn]; int dis[maxn]; int deep[maxn<<1]; int ver[maxn<<1]; int pos[maxn]; int tot=0; void dfs(int u,int step) { vis[u]=true; ver[++tot]=u;pos[u]=tot;deep[tot]=step; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; int w=edge[i].w; if(!vis[v]) { dis[v]=dis[u]+w; dfs(v,step+1); ver[++tot]=u,deep[tot]=step; } } } int dp[maxn<<1][30]; void st(int n) { int k=(int)(log((double)n)/log(2.0)); for(int i=1;i<=n;i++) dp[i][0]=i; for(int j=1;j<=k;j++) { for(int i=1;i+(1<<j)-1<=n;++i) { int x=dp[i][j-1],y=dp[i+(1<<(j-1))][j-1]; if(deep[x]<deep[y]) dp[i][j]=x; else dp[i][j]=y; } } } int lca(int x,int y) { int a=pos[x],b=pos[y]; if(a>b) swap(a,b); int k=(int)(log((double)(b-a+1))/log(2.0)); int l=dp[a][k],r=dp[b-(1<<k)+1][k]; return deep[l]<deep[r] ? ver[l]: ver[r]; } void init() { cnt=0; tot=0; memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); memset(dis,0,sizeof(dis)); } int main() { int T; scanf("%d",&T); while(T--) { init(); int n,m; scanf("%d%d",&n,&m); for(int i=1;i<n;++i) { int u,v,w; scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); addedge(v,u,w); } dfs(1,1); st(tot); while(m--) { int u,v; scanf("%d%d",&u,&v); long long ans=dis[u]+dis[v]-2*dis[lca(u,v)]; printf("%I64d\n",ans); } } return 0; }
转载请注明原文地址: https://www.6miu.com/read-25635.html

最新回复(0)