[LCA][CODEVS 2370]小机房的树

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
void read(int& n)
{
	char c = getchar();
	int tot = 0;
	while(c<'0'||c>'9')c=getchar();
	while(c>='0'&&c<='9')
	{
		tot = tot *10+c-'0';
		c=getchar();
	}
	n = tot;
}
int u,v,w;
int n,m;
const int maxn = 50010;
struct edge
{
	int v,w,next;
}e[maxn*2];
int k=1;
int head[maxn];
void adde(int u,int v,int w)
{
	e[k].v=v;
	e[k].w=w;
	e[k].next=head[u];
	head[u]=k++;
}
int d[maxn];
int f[maxn][22];
long long dis[maxn];
void dfs(int u,int fa)
{
	f[u][0]=fa;
	d[u]=d[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!=-1;i=e[i].next)
	{
		if(e[i].v!=fa)
		{
			dis[e[i].v]=dis[u]+e[i].w;
			dfs(e[i].v,u);
		}
	}
}
int lca(int a,int b)
{
	if(d[a]>d[b])swap(a,b);
	for(int i=20;i>=0;i--)
		if(d[a]<=d[b]-(1<<i))
			b = f[b][i];
	if(a==b)return a;
	for(int i=20;i>=0;i--)
	{
		if(f[a][i]==f[b][i])
			continue;
		a=f[a][i];
		b=f[b][i];		
	}
	return f[a][0];
}
int main()
{
	
	memset(head,-1,sizeof(head));
	read(n);
	dis[0]=dis[1]=0;
	for(int i=1;i<n;i++)
	{
		read(u),read(v),read(w);
		u++,v++;
		adde(u,v,w);
		adde(v,u,w);
	}
	dfs(1,0);
	read(m);
	for(int i=1;i<=m;i++)
	{
		read(u),read(v);
		u++,v++;
		int fa = lca(u,v);
		printf("%lld\n",dis[u]+dis[v]-(dis[lca(u,v)])*2);		
	}
	return 0;
}

你可能感兴趣的:([LCA][CODEVS 2370]小机房的树)