【HDU2586】How far away ?【离线】【TarjanLCA】

【题目链接】

学习一发高端的TarjanLCA。

注意并查集合并时必须用v的父亲与u的父亲合并。

/* Pigonometry */
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

const int maxn = 40005, maxm = 205;

int n, m, head[maxn], cnt, fa[maxn], dis[maxn], vis[maxn], clo, ans[maxm];

struct _edge {
	int v, w, next;
} g[maxn << 1];

struct _query {
	int v, qid;
};

vector<_query> query[maxn];

inline int iread() {
	int f = 1, x = 0; char ch = getchar();
	for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
	for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
	return f * x;
}

inline void add(int u, int v, int w) {
	g[cnt] = (_edge){v, w, head[u]};
	head[u] = cnt++;
}

inline int find(int x) {
	return fa[x] == x ? x : fa[x] = find(fa[x]);
}

inline void tarjan(int x) {
	vis[x] = clo;
	for(int i = head[x]; ~i; i = g[i].next) if(vis[g[i].v] != clo) {
		dis[g[i].v] = dis[x] + g[i].w;
		tarjan(g[i].v);
		fa[find(g[i].v)] = find(x);
	}
	for(int i = 0; i < query[x].size(); i++) if(vis[query[x][i].v] == clo) {
		int v = query[x][i].v, qid = query[x][i].qid;
		ans[qid] = dis[x] + dis[v] - 2 * dis[find(v)];
	}
}

int main() {
	for(int T = iread(); T; T--) {
		n = iread(); m = iread();
		for(int i = 1; i <= n; i++) head[i] = -1, fa[i] = i, query[i].clear(); cnt = 0;

		for(int i = 1; i < n; i++) {
			int u = iread(), v = iread(), w = iread();
			add(u, v, w); add(v, u, w);
		}
		for(int i = 1; i <= m; i++) {
			int u = iread(), v = iread();
			query[u].push_back((_query){v, i});
			query[v].push_back((_query){u, i});
		}

		clo++;
		tarjan(1);

		for(int i = 1; i <= m; i++) printf("%d\n", ans[i]);
	}
	return 0;
}


你可能感兴趣的:(【HDU2586】How far away ?【离线】【TarjanLCA】)