带权树上距离求调qwq
  • 板块灌水区
  • 楼主Rainsleep
  • 当前回复0
  • 已保存回复0
  • 发布时间2022/11/8 20:41
  • 上次更新2023/10/27 03:42:36
查看原帖
带权树上距离求调qwq
666796
Rainsleep楼主2022/11/8 20:41
#include<bits/stdc++.h>

using namespace std;

#define int long long 

const int N = 200010;

struct Edge
{
	int from;
	int to;
	int w;
	int nxt;
} edges[N << 1];

int dist[N]; //到跟距离

int head[N], idx = 0, n;

inline void link(int x, int y, int w)
{
	++ idx;
	edges[idx] = {x, y, w, head[x]};
	head[x] = idx;
	return ;
}

int fa[N][30], depth[N]; // 权值和

inline void dfs(int cur, int pa, int w)
{
	fa[cur][0] = pa;
	depth[cur] = depth[pa] + w;
	dist[cur] = dist[pa] + 1;
		
	for(int i(1);i <= 25; ++ i)
		fa[cur][i] = fa[fa[cur][i - 1]][i -1];
		
	for(int i(head[cur]);i;i = edges[i].nxt)
	{
		int to = edges[i].to;
		int w = edges[i].w;
		
		if(to == pa)
			continue;
		
		dfs(to, cur, w);
	}
	
	return ;
}

inline int lca(int from, int to)
{
	if(dist[from] < dist[to])
	{
		/*
		from = from ^ to;
		to = from ^ to;
		from = from ^ to;
		*/
		swap(from, to);
	}
	
	int d = dist[from] - dist[to];
	
	for(int i(0);i <= 25; ++ i)
	{
		if(d & 1)
			from = fa[from][i];
		d >>= 1;
	}
	
	if(from == to)
		return from;
		
	for(int i(25);i; -- i)
	{
		if(fa[from][i] == fa[to][i])
			continue;
		from = fa[from][i];
		to = fa[to][i];
	}
	
	return fa[from][0];
}

inline int dis(int from, int to)
{
	int p = lca(from, to);
	//printf("LCA %lld\n", p);
	int res = depth[from] + depth[to] - (depth[p] << 1);
	return res;
}

signed main()
{
	int T;
	
	scanf("%lld %lld", &n, &T);
	
	for(int i(1);i <= n - 1; ++ i)
	{
		int x, y, k;
		scanf("%lld %lld %lld", &x, &y, &k);
		
		link(x, y, k);
		link(y, x, k);
	}

	dfs(1, 0, 0);
	
	//printf("%lld\n", depth[2]);
	
	while(T -- )
	{
		int x, y;
		scanf("%lld %lld", &x, &y);
		printf("%lld", dis(x, y));
		putchar('\n');
	}
	
	return 0;
}

qwq

2022/11/8 20:41
加载中...