就是倍增的裸题,给你一棵树,求两点间最大距离
不说那么多,直接放代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<stack>
#define INF 2100000000
#define ll long long
#define clr(x) memset(x,0,sizeof(x))
#define clrmax(x) memset(x,127,sizeof(x))
using namespace std;
inline int read()
{
char c;
int ret=0;
while(!(c>='0'&&c<='9'))
c=getchar();
while(c>='0'&&c<='9')
{
ret=(c-'0')+(ret<<1)+(ret<<3);
c=getchar();
}
return ret;
}
#define M 40005
int t,m,n;
int bz[21][M],bzn[21][M];
int fa[M],w[M],d[M],dep[M];
int first[M],to[M*2],lext[M*2];
void addedge(int s,int v,int val)
{
lext[++t]=first[s];
first[s]=t;
to[t]=v;
d[t]=val;
}
void dfs(int x)
{
for(int i=first[x];i;i=lext[i])
{
int v=to[i];
if(v==bz[0][x])continue;
bz[0][v]=x;
bzn[0][v]=d[i];
dep[v]=dep[x]+1;
dfs(v);
}
}
void get_bz()
{
for(int i=1;i<=20;i++)
for(int j=1;j<=n;j++)
{
bz[i][j]=bz[i-1][bz[i-1][j]];
bzn[i][j]=bzn[i-1][j]+bzn[i-1][bz[i-1][j]];
}
}
int lca(int s,int v)
{
int ret=0;
if(dep[v]>dep[s])
swap(s,v);
int dh=dep[s]-dep[v];
for(int i=0;i<=20;i++)
{
if(1<<i&dh)
{
ret+=bzn[i][s];
s=bz[i][s];
}
}
if (s==v) return ret;
for(int i=20;i>=0;i--)
{
if(bz[i][s]!=bz[i][v])
{
ret+=bzn[i][s];
ret+=bzn[i][v];
s=bz[i][s];
v=bz[i][v];
}
}
ret+=bzn[0][s];ret+=bzn[0][v];
return ret;
}
int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
int q;
scanf("%d",&q);
while(q--)
{
clr(lext);clr(first);clr(to);clr(d);
clr(w);clr(bz);clr(bzn);clr(dep);clr(fa);
t=0;
n=read();m=read();
for(int i=1;i<n;i++)
{
//int a,b,c;
//scanf("%d%d%d",&a,&b,&c);
int a=read(),b=read(),c=read();
addedge(a,b,c);
addedge(b,a,c);
}
bz[0][1]=1;
dfs(1);
get_bz();
for(int i=1;i<=m;i++)
{
//int a,b;
//scanf("%d%d",&a,&b);
int a=read(),b=read();
cout<<lca(a,b)<<'\n';
}
cout<<'\n';
}
return 0;
}
大概就是这个样子,如果有什么问题,或错误,请在评论区提出,谢谢。