lca裸题,我们对三个点两两求lca,我们知道这三个lca至少有两个相同,所以选择另外一个lca最短(可自行画图YY),之后瞎搞就好了。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cmath> 7 #define MAXN 500005 8 using namespace std; 9 int read(){ 10 int x=0,f=1;char ch=getchar(); 11 while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();} 12 while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();} 13 return x*f; 14 } 15 struct data{ 16 int to,next; 17 }e[2*MAXN]; 18 int head[MAXN],cnt; 19 void add(int u,int v){e[cnt].to=v;e[cnt].next=head[u];head[u]=cnt;cnt++;} 20 int n,m; 21 int f[MAXN][28]; 22 int dep[MAXN]; 23 void dfs(int now,int fa){ 24 for(int i=1;i<=25;i++){ 25 if((1<<i)>=dep[now]) break; 26 f[now][i]=f[f[now][i-1]][i-1]; 27 } 28 for(int i=head[now];i>=0;i=e[i].next){ 29 int to=e[i].to; 30 if(to==fa) continue; 31 dep[to]=dep[now]+1;f[to][0]=now; 32 dfs(to,now); 33 } 34 } 35 int find(int a,int b){ 36 if(dep[a]<dep[b]) swap(a,b); 37 int t=dep[a]-dep[b]; 38 for(int i=25;i>=0;i--) if(t&(1<<i)) a=f[a][i]; 39 for(int i=25;i>=0;i--) if(f[a][i]!=f[b][i]) a=f[a][i],b=f[b][i]; 40 return a==b?a:f[a][0]; 41 } 42 int main() 43 { 44 memset(head,-1,sizeof(head)); 45 n=read(),m=read(); 46 for(int i=1;i<n;i++){ 47 int a=read(),b=read(); 48 add(a,b);add(b,a); 49 } 50 f[1][0]=0;dep[1]=1; 51 dfs(1,0); 52 for(int i=1;i<=m;i++){ 53 int a=read(),b=read(),c=read(); 54 int lca1=find(a,b),lca2=find(a,c),lca3=find(b,c); 55 if(lca1==lca2) printf("%d %d ",lca3,dep[b]+dep[c]-2*dep[lca3]+dep[a]-dep[lca1]+dep[lca3]-dep[lca1]); 56 else if(lca1==lca3) printf("%d %d ",lca2,dep[a]+dep[c]-2*dep[lca2]+dep[b]-dep[lca1]+dep[lca2]-dep[lca1]); 57 else if(lca2==lca3) printf("%d %d ",lca1,dep[a]+dep[b]-2*dep[lca1]+dep[c]-dep[lca2]+dep[lca1]-dep[lca2]); 58 } 59 } 60