Run Time: 0.330
Ranking (as of 2016-01-11): 31 out of 359
Language: C++
For explanation, see Range Minimum Query and Lowest Common Ancestor - topcoder.
/* UVa 12238 - Ants Colony To build using Visual Studio 2012: cl -EHsc -O2 UVa_12238_Ants_Colony.cpp */ #include <algorithm> #include <vector> #include <cstdio> #ifdef __ELAPSED_TIME__ #include <ctime> #endif using namespace std; const int N_max = 100000; struct edge { int v_; int weight_; edge(int v, int weight) : v_(v), weight_(weight) {} }; vector<edge> edges[N_max]; const int level_max = 17; // ceil(log2(N_max)) int levels[N_max]; // level (depth) of node i in the tree long long weights[N_max]; // weights[i] is the total length from the root to i-th node int parents[N_max]; // parent node of i int ancestors[N_max][level_max + 1]; // ancestors[i][j] is the 2^j-th ancestor of node i void dfs(int u, int parent, int level) { levels[u] = level; const vector<edge>& mes = edges[u]; for (size_t i = 0; i < mes.size(); i++) { int v = mes[i].v_, w = mes[i].weight_; if (v != parent) { parents[v] = u, weights[v] = w + weights[u]; dfs(v, u, level + 1); } } } void process3(int n) { for (int i = 0 ; i < n; i++) { // the first ancestor of every node i is parents[i] ancestors[i][0] = parents[i]; for (int j = 1; 1 << j < n; j++) ancestors[i][j] = -1; } for (int j = 1; 1 << j < n; j++) for (int i = 0; i < n; i++) if (ancestors[i][j - 1] != -1) ancestors[i][j] = ancestors[ancestors[i][j - 1]][j - 1]; } long long query(int p, int q) { long long w = weights[p] + weights[q]; //if p is situated on a higher level than q then we swap them if (levels[p] < levels[q]) swap(p, q); // we compute the value of [log2(level[p)] int log; for (log = 1; 1 << log <= levels[p]; log++) ; log--; // we find the ancestor of node p situated on the same level // with q using the values in ancestors[][] for (int i = log; i >= 0; i--) if (levels[p] - (1 << i) >= levels[q]) p = ancestors[p][i]; if (p == q) return w - weights[p] * 2; // we compute LCA(p, q) using the values in ancestors[][] for (int i = log; i >= 0;i--) if (ancestors[p][i] != -1 && ancestors[p][i] != ancestors[q][i]) p = ancestors[p][i], q = ancestors[q][i]; return w - weights[parents[p]] * 2; } int main() { #ifdef __ELAPSED_TIME__ clock_t start = clock(); #endif while (true) { int N; scanf("%d", &N); if (!N) break; for (int i = 0; i < N; i++) edges[i].clear(); for (int v = 1; v < N; v++) { int u, w; scanf("%d %d", &u, &w); edges[u].push_back(edge(v, w)), edges[v].push_back(edge(u, w)); } dfs(0, -1, 0); process3(N); int Q; scanf("%d", &Q); while (Q--) { int s, t; scanf("%d %d", &s, &t); printf("%lld%c", query(s, t), ((Q) ? ' ' : '\n')); } } #ifdef __ELAPSED_TIME__ fprintf(stderr, "elapsed time = %lf sec.\n", static_cast<double>(clock() - start) / CLOCKS_PER_SEC); #endif return 0; }
No comments:
Post a Comment