比赛 ZLXOI2015Day2 评测结果 AWWWWWWWWW
题目名称 ZLX的陨落 最终得分 10
用户昵称 lyxin65 运行时间 0.386 s
代码语言 C++ 内存使用 12.52 MiB
提交时间 2015-10-30 20:44:41
显示代码纯文本
#include <bits/stdc++.h>

using namespace std;

const int maxn = 100005;
const int maxm = 200005;
const int maxlog = 20;

int n, m, logn;
int head[maxn];
int next[maxm];
int u[maxm], v[maxm], w[maxm];

void init_graph()
{
	while((1 << (logn + 1)) < n) ++logn;
	memset(head, -1, sizeof(head)), m = 0;
}

inline void addedge(int a, int b, int c)
{
	u[m] = a, v[m] = b, w[m] = c;
	next[m] = head[a], head[a] = m++;
}

void input()
{
	init_graph();
	
	register int mm;
	scanf("%d%d", &n, &mm);
	for(int i = 1; i <= mm; ++i)
	{
		int x, y, z;
		scanf("%d%d%d", &x, &y, &z);
		addedge(x, y, z);
		addedge(y, x, z);
	}
}


int depth[maxn];
long long dis[maxn];
int fa[maxn][maxlog];

void bfs()
{
	queue<int> q;
	q.push(1);
	while(!q.empty())
	{
		int x = q.front(); q.pop();
		for(int i = head[x]; ~i; i = next[i])
		{
			if(v[i] != fa[x][0])
			{
				fa[v[i]][0] = x;
				dis[v[i]] = dis[x] + w[i];
				depth[v[i]] = depth[x] + 1;
				q.push(v[i]);
			}
		}
	}
}

void init_lca()
{
	for(int j = 1; j <= logn; ++j)
		for(int i = 1; i <= n; ++i)
			fa[i][j] = fa[fa[i][j-1]][j-1];
}

void build()
{
	bfs();
	init_lca();
}

int lca(int a, int b)
{
	if(depth[a] < depth[b]) swap(a, b);
	for(int j = logn; j >= 0; --j)
		if(depth[fa[a][j]] >= depth[b])
			a = fa[a][j];
	if(a == b) return a;
	for(int j = logn; j >= 0; --j)
		if(fa[a][j] != fa[b][j])
			a = fa[a][j], b = fa[b][j];
	return fa[a][0];
}

void solve()
{
	int Q;
	scanf("%d", &Q);
	while(Q--)
	{
		int a, b;
		scanf("%d%d", &a, &b);
		printf("%lld\n", dis[a] + dis[b] - 2 * dis[lca(a, b)]);
	}
}

int main()
{
	freopen("ThefallingofZLX.in", "r", stdin);
	freopen("ThefallingofZLX.out", "w", stdout);
	
	input();
	build();
	solve();
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}