LCA题目
这题不就是改成三个点的LCA吗?
首先求出三个点中两两的LCA,如果有两个LCA相等,那么三个点的LCA就是另外那对点的LCA
int fa1=lca(u,v),fa2=lca(v,w),fa3=lca(w,u); if(fa1==fa2)printf("%d ",fa3); if(fa2==fa3)printf("%d ",fa1); if(fa3==fa1)printf("%d ",fa2);
最后三个点深度和减去三个LCA的深度和就是金币数
看着他这么水就马上把代码从我博客里弄下来改一改交上去
#include<bits/stdc++.h> using namespace std; struct edge{ int to,next; }ed[100005]; int n,m,u,v,w,cnt,head[50005],dep[50005],f[50005][20]; void add(int u,int v){ cnt++; ed[cnt].to=v; ed[cnt].next=head[u]; head[u]=cnt; } void dfs(int u,int fa){ f[u][0]=fa; dep[u]=dep[fa]+1; for(int i=1;i<20;i++)f[u][i]=f[f[u][i-1]][i-1]; for(int i=head[u];i;i=ed[i].next){ int v=ed[i].to; if(v!=fa)dfs(v,u); } } int lca(int u,int v){ if(dep[u]<dep[v])swap(u,v); for(int i=19;i>=0;i--)if(dep[u]-(1<<i)>=dep[v])u=f[u][i]; if(u==v)return u; for(int i=19;i>=0;i--)if(f[u][i]!=f[v][i])u=f[u][i],v=f[v][i]; return f[u][0]; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<n;i++){ scanf("%d%d",&u,&v); add(u,v),add(v,u); } dfs(1,0); for(int i=1;i<=m;i++){ scanf("%d%d%d",&u,&v,&w); int fa1=lca(u,v),fa2=lca(v,w),fa3=lca(w,u); if(fa1==fa2)printf("%d ",fa3); if(fa2==fa3)printf("%d ",fa1); if(fa3==fa1)printf("%d ",fa2); printf("%d\n",dep[u]+dep[v]+dep[w]-dep[fa1]-dep[fa2]-dep[fa3]); } }
结果RE两个点
忘改数组了(无语)
数组调大后就A了
来源:https://www.cnblogs.com/gzezzry/p/12190196.html