你猜这是啥
裸的LCA
以dis数组为从根到当前节点的总距离
u,v的最小距离即为
dis[u]+dis[v]-2*dis[LCA(u,v)]
至于LCA的实现方法是Tarjan,不会的可以看我上篇BLOG!
#include <cstdio>
#include <iostream>
using namespace std;
const int maxm=501000;
struct node{
int net;
int to;
int cost;
int lca;
int ans;
};
bool vis[maxm];
int fat[maxm];
node edge[2][2*maxm];
int cnt[2],head[2][maxm];
int dis[maxm];
void add(int id,int x,int y,int c)
{
edge[id][++cnt[id]].to=y;
edge[id][cnt[id]].cost=c;
edge[id][cnt[id]].net=head[id][x];
head[id][x]=cnt[id];
}
int find(int x)
{
if(fat[x]==x) return x;
else return fat[x]=find(fat[x]);
}
void dfs(int x,int f,int sum)
{
dis[x]+=dis[f]+sum;
vis[x]=1;
fat[x]=x;
for(int K=head[0][x];K;K=edge[0][K].net)
{
int p=edge[0][K].to;
if(vis[p]) continue;
dfs(p,x,edge[0][K].cost);
fat[p]=x;
}
for(int i=head[1][x];i;i=edge[1][i].net)
{
int p=edge[1][i].to;
if(!vis[p]) continue;
edge[1][i].lca=find(p);
int ans=dis[x]+dis[p]-2*dis[edge[1][i].lca];
edge[1][i].ans=ans;
if(i%2)
edge[1][i+1].lca=edge[1][i].lca,edge[1][i+1].ans=ans;
else
edge[1][i-1].lca=edge[1][i].lca,edge[1][i-1].ans=ans;
}
}
int main()
{
int n,m;
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
add(0,x,y,c);
add(0,y,x,c);
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(1,x,y,0),add(1,y,x,0);
}
dfs(1,0,0);
for(int i=1;i<=m;i++)
{
printf("%d\n",edge[1][2*i].ans);
}
}