比赛 ZLXOI2015Day2 评测结果 AAAAAAAAAA
题目名称 ZLX的陨落 最终得分 100
用户昵称 Skyo 运行时间 0.768 s
代码语言 C++ 内存使用 41.49 MiB
提交时间 2015-10-30 19:32:25
显示代码纯文本
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long L;

int n, m, q, d[100005]; L F[100005][25], D[100005][25];
int h[100005], nx[200005], v[200005], w[200005];

void Initialize()
{
	freopen("ThefallingofZLX.in", "r", stdin);
	freopen("ThefallingofZLX.out", "w", stdout);
	scanf("%d %d", &n, &m);
	for(int i = 1; i <= m; i++)
	{
		int ui, vi, wi; scanf("%d %d %d", &ui, &vi, &wi);
		int e1 = i*2-1, e2 = i*2;
		nx[e1] = h[ui], h[ui] = e1, v[e1] = vi, w[e1] = wi;
		nx[e2] = h[vi], h[vi] = e2, v[e2] = ui, w[e2] = wi;
	}
	scanf("%d", &q);
}

void DFS(int u, int fa)
{
	F[u][0] = fa;
	d[u] = d[fa] + 1;
	for(int i = 1; (1<<i) <= d[u]; i++)
	{
		F[u][i] = F[F[u][i-1]][i-1];
		D[u][i] = D[F[u][i-1]][i-1] + D[u][i-1];	
	}	
	for(int i = h[u]; i; i = nx[i]) if(v[i] != fa)
	{
		D[v[i]][0] = w[i];
		DFS(v[i], u);
	}
}

L LCA(int a, int b)
{
	L res = 0;
	if(d[a] < d[b]) swap(a, b);
	while(d[a] != d[b])
	{
		int k = 2+(int)(log(d[a]-d[b])/log(2.0));
		while(d[F[a][k]] < d[b] && k) k--;
		res += D[a][k]; a = F[a][k];
	}
	if(a == b) return res;
	while(a != b)
	{
		int k = 18;
		while(F[a][k] == F[b][k] && k) k--;
		res += D[a][k] + D[b][k];
		a = F[a][k], b = F[b][k];
	}
	return res;
}

int main()
{
	Initialize();
	DFS(1, 0);
	while(q--)
	{
		int ui, vi; scanf("%d %d", &ui, &vi);
		printf("%lld\n", LCA(ui, vi));
	}
	return 0;
}