题目连接
http://acm.hdu.edu.cn/showproblem.php?pid=2586
How far away ?
Description
There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B"? Usually it hard to answer. But luckily int this village the answer is always unique, since the roads are built in the way that there is a unique simple path("simple" means you can't visit a place twice) between every two houses. Yout task is to answer all these curious people.
Input
First line is a single integer T(T<=10), indicating the number of test cases.
For each test case,in the first line there are two numbers n(2<=n<=40000) and m (1<=m<=200),the number of houses and the number of queries. The following n-1 lines each consisting three numbers i,j,k, separated bu a single space, meaning that there is a road connecting house i and house j,with length k(0<k<=40000).The houses are labeled from 1 to n.
Next m lines each has distinct integers i and j, you areato answer the distance between house i and house j.
Output
For each test case,output m lines. Each line represents the answer of the query. Output a bland line after each test case.
Sample Input
2
3 2
1 2 10
3 1 15
1 2
2 3
2 2
1 2 100
1 2
2 1
Sample Output
10
25
100
100
tarjan离线求LCA。。
#include <bits/stdc++.h> using namespace std; const int N = 40010; struct Tarjan_Lca { bool vis[N]; vector<pair<int, int>> A, Q[N]; int tot, par[N], ans[210], head[N], dist[N]; struct edge { int to, w, next; }G[N << 1]; inline void init(int n) { A.clear(); for(int i = 0; i < n + 2; i++) { par[i] = i; vis[i] = false; head[i] = -1; dist[i] = 0; Q[i].clear(); } } inline void add_edge(int u, int v, int w) { G[tot] = { v, w, head[u] }, head[u] = tot++; G[tot] = { u, w, head[v] }, head[v] = tot++; } inline void built(int n, int m) { int u, v, w; while(n-- > 1) { scanf("%d %d %d", &u, &v, &w); add_edge(u, v, w); } for(int i = 0; i < m; i++) { scanf("%d %d", &u, &v); A.push_back(pair<int, int>(u, v)); Q[u].push_back(pair<int, int>(v, i)); Q[v].push_back(pair<int, int>(u, i)); } } inline int find(int x) { while(x != par[x]) { x = par[x] = par[par[x]]; } return x; } inline void tarjan(int u, int fa) { for(int i = head[u]; ~i; i = G[i].next) { edge &e = G[i]; if(e.to == fa) continue; dist[e.to] = dist[u] + e.w; tarjan(e.to, u); vis[e.to] = true; par[e.to] = u; } for(auto &r: Q[u]) { if(vis[r.first]) ans[r.second] = find(r.first); } } inline void solve(int n, int m) { init(n); built(n, m); tarjan(1, 1); for(int i = 0; i < m; i++) { printf("%d ", dist[A[i].first] + dist[A[i].second] - 2 * dist[ans[i]]); } } }go; int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); freopen("out.txt", "w+", stdout); #endif int t, n, m; scanf("%d", &t); while(t--) { scanf("%d %d", &n, &m); go.solve(n, m); } return 0; }