【LCA】SPOJ QTREE2
来源:互联网 发布:淘宝改差评先打钱 编辑:程序博客网 时间:2024/06/06 12:57
We will ask you to perfrom some instructions of the following form:
- DIST a b : ask for the distance between node a and node b
or - KTH a b k : ask for the k-th node on the path from node a to node b
Example:
N = 6
1 2 1 // edge connects node 1 and node 2 has cost 1
2 4 1
2 5 2
1 3 1
3 6 2
Path from node 4 to node 6 is 4 -> 2 -> 1 -> 3 -> 6
DIST 4 6 : answer is 5 (1 + 1 + 1 + 2 = 5)
KTH 4 6 4 : answer is 3 (the 4-th node on the path from node 4 to node 6 is 3)
Input
The first line of input contains an integer t, the number of test cases (t <= 25). t test cases follow.
For each test case:
- In the first line there is an integer N (N <= 10000)
- In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between a, b of cost c (c <= 100000)
- The next lines contain instructions "DIST a b" or "KTH a b k"
- The end of each test case is signified by the string "DONE".
There is one blank line between successive tests.
Output
For each "DIST" or "KTH" operation, write one integer representing its result.
Print one blank line after each test.
Example
Input:161 2 12 4 12 5 21 3 13 6 2DIST 4 6KTH 4 6 4DONEOutput:53 LCA, 开disRt[u]数组表示节点u到根的距离,用倍增法求节点u与v的LCA(w), 则dis(u, v) = (disRt[u] - disRt[w]) + (disRt[v] - disRt[w]). u至v路径上第k个节点则讨论其是u的祖先还是v的祖先, 再二分查找即可.
<span style="font-family:Courier New;">#include <cstdio>#include <iostream>#include <cstdlib>#include <memory.h>#include <ctime>#include <algorithm>#include <cmath>#include <cstring>#include <string>#include <utility>#include <stack>#include <set>#include <map>#include <queue>#include <vector>#include <climits>using namespace std;#define clr(_arr) (memset(_arr, 0, sizeof(_arr)))typedef long long ll;const int INF = INT_MAX, N_MAX = 10010, LG_N_MAX = 20;int N, LG_N, a, b, c, root = 1, par[LG_N_MAX][N_MAX],//par[m][u] indicates the (2 ^ m)th ancestor of u dep[N_MAX], disRt[N_MAX];char instr[8];vector<int> G[N_MAX];typedef pair<int, int> pii;map<pii, int> len;void init(){ clr(par); clr(dep); clr(disRt); for (int i = 1; i <= N; ++i) G[i].clear(); len.clear(); LG_N = 0; int _N = 1; while (_N <= N) { _N <<= 1; ++LG_N; } ++LG_N;}void addEdge(int a, int b, int c){ G[a].push_back(b); G[b].push_back(a); len[make_pair(a, b)] = c; len[make_pair(b, a)] = c;}void dfs(int u, int p, int d, int dR){ par[0][u] = p; dep[u] = d; disRt[u] = dR; int out = G[u].size(); for (int i = 0; i < out; ++i) { int s = G[u][i]; if (s != p) dfs(s, u, d + 1, dR + len[pii(u, s)]); }}void pre(){ dfs(root, -1, 0, 0); //par[m + 1][u] can be obtained only after all par[m][v](v = 1..N) is obtained, and thus the outer loop should be of u for (int u = 1; u <= N; ++u) for (int m = 0; m + 1 <= LG_N; ++m) { if (par[m][u] < 0) par[m + 1][u] = -1; else par[m + 1][u] = par[m][par[m][u]]; }}int kthAnt(int u, int k){ for (int m = 0; k; ++m, k >>= 1) { if (k & 1) u = par[m][u]; } return u;}int LCA(int u, int v){ if (dep[u] < dep[v]) swap(u, v); u = kthAnt(u, dep[u] - dep[v]); if (u == v) return u; //binary search, search all ancestors of u and v for the last different node index pair, whose parent is LCA(u, v) for (int m = LG_N; m >= 0; --m) if (par[m][u] != par[m][v]) { u = par[m][u]; v = par[m][v]; } return par[0][u];}int Kth(int u, int v, int k){ int w = LCA(u, v); int uw = dep[u] - dep[w] + 1, wv = dep[v] - dep[w] + 1, _k = k; k = (_k <= uw) ? k : (wv - (k - uw)); u = (_k <= uw) ? u : v; return kthAnt(u, k - 1);}int main(){ int t; scanf("%d", &t); while(t--) { bool done = false; scanf("%d", &N); init(); for (int i = 1; i < N; ++i) { scanf("%d %d %d", &a, &b, &c); addEdge(a, b, c); } pre(); getchar(); while(!done) { scanf("%s", instr); switch (instr[1]) { case 'I': { scanf("%d %d\n", &a, &b); int w = LCA(a, b); int dis = disRt[a] + disRt[b] - 2 * disRt[w]; printf("%d\n", dis); break; } case 'T': { int k; scanf("%d %d %d\n", &a, &b, &k); printf("%d\n", Kth(a, b, k)); break; } case 'O': { done = true; break; } } } printf("\n"); } return 0;}</span>
0 0
- 【LCA】SPOJ QTREE2
- SPOJ QTree2
- SPOJ QTREE2 Query on a tree II (倍增LCA)
- SPOJ-QTREE2 Query on a tree II(暴力+LCA)
- SPOJ QTREE2 Query on a tree II 倍增lca
- 【动态树】 SPOJ QTREE2
- SPOJ QTREE2 lct
- 【树结构】SPOJ QTREE2
- SPOJ QTREE2 Query on a tree II
- 【spoj】【QTREE2 - Query on a tree II】
- SPOJ QTREE2 Query on a tree II(lct)
- SPOJ COT (主席树 LCA)
- SPOJ LCA Lowest Common Ancestor
- 动态树LCT(SPOJ QTREE2 - Query on a tree II)
- SPOJ——QTREE2 - Query on a tree II(树链剖分或者倍增法)
- Spoj Query on a tree II (LCA)
- SPOJ:Terrorists(LCA + SPFA最短路)
- spoj Query on a tree2(LCA)
- 第二十一章 泛型(generic)
- hadoop2
- sql 中如何将A表的数据更新到B表中,数据表备份语句
- Triangle
- Servlet之避免页面被直接访问到
- 【LCA】SPOJ QTREE2
- N-Queens
- 解决解析xml报UTFDataFormatException方案
- leetcode:Container With Most Water
- [C++学习笔记]--常量对象、常量成员函数和常引用
- hdu 5347 MZL's chemistry
- 注解 Annotation
- 【Android-BUG篇】error opening trace file: No such file or directory
- javascript设计模式之单例(singleton)模式