比较经典的LCA问题,如果掌握了Tarjan算法后,这题就很容易地水过了~~
本人在学习Tarjan算法时,参考了ylfdrib的博客:http://www.cnblogs.com/ylfdrib/archive/2010/11/03/1867901.html, 感觉他讲得比较清晰易懂,而且又有相关的代码参考。
#include<stdio.h> #include<string.h> #include<vector> #include<algorithm> using namespace std; const int maxn = 100010; const int maxm = 100010; struct node { int v; unsigned long long d; }; node tmp; vector<node> g[maxn]; vector<node> q[maxn]; int p[maxn]; int anc[maxn]; bool vis[maxn]; unsigned long long dis[maxn]; unsigned long long res[maxm][3]; int n, m; void init() { for(int i = 0; i <= n; i++) { p[i] = i; dis[i] = 0; vis[i] = false; anc[i] = i; g[i].clear(); q[i].clear(); } } int find(int a) { return p[a] == a ? a : (p[a] = find(p[a])); } void LCA(int u) { anc[u] = u; vis[u] = true; for(int i = 0; i < q[u].size(); i++) { tmp = q[u][i]; if(vis[tmp.v]) res[tmp.d][2] = anc[find(tmp.v)]; } for(int i = 0; i < g[u].size(); i++) { tmp = g[u][i]; int v = tmp.v; if(!vis[v]) { dis[v] = dis[u] + tmp.d; LCA(v); int x = find(u); int y = find(v); if(x != y) p[y] = x; anc[x] = u; } } } #define LOCAL int main() { #ifdef LOCAL freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); #endif while(scanf("%d", &n) == 1) { if(n == 0) break; init(); int a, b; long long c; for(int i = 1; i < n; i++) { a = i; scanf("%d%lld", &b, &c); tmp.v = b; tmp.d = c; g[a].push_back(tmp); tmp.v = a; tmp.d = c; g[b].push_back(tmp); } scanf("%d", &m); for(int i = 0; i < m; i++) { scanf("%d%d", &a, &b); tmp.v = b; tmp.d = i; q[a].push_back(tmp); tmp.v = a; tmp.d = i; q[b].push_back(tmp); res[i][0] = a; res[i][1] = b; } dis[0] = 0; LCA(0); for(int i = 0; i < m-1; i++) printf("%llu ", dis[res[i][0]] + dis[res[i][1]] - 2*dis[res[i][2]]); printf("%llu/n", dis[res[m-1][0]] + dis[res[m-1][1]] - 2*dis[res[m-1][2]]); } return 0; }