[Usaco2004 Feb]Distance Queries 距离咨询 题解

今天产题解效率有点高啊

其实全是切的板子题

solve

  • 显然,路径构成树
  • 求两点距离,显然lca
  • 然后就和Pasture Walking G 牧场散步 题解没啥区别了
  • 然后就没有然后了
  • 那个方向没有用,输入进来就不用管了

Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=1000010;
int n,m,s;
int h[maxn],nxt[maxn],to[maxn],tot,w[maxn];
int Log[maxn];
int dep[maxn];
int dis[maxn];
int fa[maxn][20];
void add(int x,int y,int z)
{
	tot++;
	to[tot]=y;
	w[tot]=z;
	nxt[tot]=h[x];
	h[x]=tot;
}
void llog(){for (int i=2;i<=n;i++) Log[i]=Log[i>>1]+1;}
void dfs(int now,int f)
{
	dep[now]=dep[f]+1;
	fa[now][0]=f;
	for (int i=1;i<=19;i++)
	{
		fa[now][i]=fa[fa[now][i-1]][i-1];
	}
	for (int i=h[now];i;i=nxt[i])
	{
		int y=to[i];
		if (y==f) continue;
		dis[y]=dis[now]+w[i];
		dfs(y,now);
	}
}
int lca(int x,int y)
{
	if (dep[x]>dep[y]) swap(x,y);
	int d=dep[y]-dep[x];
	for (int i=Log[d];i>=0;i--)
	{
		if (d>>i&1) y=fa[y][i]; 
	}
	if (x == y) return x;
	for (int i=Log[dep[x]];i>=0;i--)
	{
		if (fa[x][i]!=fa[y][i])
		{
			x=fa[x][i];
			y=fa[y][i];
		}
	}
	return fa[x][0];
}
int main()
{
	cin >> n >> m;
	llog();
	for (int i=1;i<=n-1;i++)
	{
		int x,y,z;
		char op;
		cin >> x >> y >> z >> op;
		add(x,y,z);
		add(y,x,z);
	}
	dfs(1,1);// 树根是谁都一样
	int q;
	cin >> q;
	while (q--)
	{
		int x,y;
		cin >> x >> y;
		int d=dis[x]+dis[y]-dis[lca(x,y)]*2;
		cout << d << endl;
	}
	return 0;
}
posted @ 2026-03-25 14:57  msjing  阅读(13)  评论(0)    收藏  举报