标签:
Time Limit: 433MS | Memory Limit: 1572864KB | 64bit IO Format: %lld & %llu |
Description
You are given a tree (an undirected acyclic connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. Each edge has an integer value assigned to it, representing its length.
We will ask you to perfrom some instructions of the following form:
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)
The first line of input contains an integer t, the number of test cases (t <= 25). t test cases follow.
For each test case:
There is one blank line between successive tests.
For each "DIST" or "KTH" operation, write one integer representing its result.
Print one blank line after each test.
Input: 1 6 1 2 1 2 4 1 2 5 2 1 3 1 3 6 2 DIST 4 6 KTH 4 6 4 DONE Output: 5 3
/** 题意:给一个树,求u->v的距离 求u->v的第k个点 做法:专题是树链划分 但是想想LCA可以求距离 第k个点 要么是u->v的第k个点 要么是第k`个点 **/ #include <iostream> #include <algorithm> #include <string.h> #include <stdio.h> #include <cmath> #include <queue> #include <set> using namespace std; const int maxn = 10010; const int DEG = 20; int main(); struct Edge { int to; int nxt; int val; } edge[maxn * 2]; int head[maxn], tot; int mmap[maxn]; void addedge(int u, int v, int w) { edge[tot].to = v; edge[tot].val = w; edge[tot].nxt = head[u]; head[u] = tot++; } void init() { tot = 0; memset(head, -1, sizeof(head)); } int fa[maxn][DEG]; int deg[maxn]; void bfs(int root) { queue<int>que; deg[root] = 0; mmap[root] = 0; fa[root][0] = root; que.push(root); while(!que.empty()) { int tmp = que.front(); que.pop(); for(int i = 1; i < DEG; i++) { fa[tmp][i] = fa[fa[tmp][i - 1]][i - 1]; } for(int i = head[tmp]; i != -1; i = edge[i].nxt) { int v = edge[i].to; if(v == fa[tmp][0]) { continue; } deg[v] = deg[tmp] + 1; mmap[v] = mmap[tmp] + edge[i].val; fa[v][0] = tmp; que.push(v); } } } int LCA(int u, int v) { if(deg[u] > deg[v]) { swap(u, v); } int hu = deg[u]; int hv = deg[v]; int tu = u; int tv = v; for(int det = hv - hu, i = 0; det; det >>= 1, i++) if(det & 1) { tv = fa[tv][i]; } if(tu == tv) { return tu; } for(int i = DEG - 1; i >= 0; i--) { if(fa[tu][i] == fa[tv][i]) { continue; } tu = fa[tu][i]; tv = fa[tv][i]; } return fa[tu][0]; } bool flag[maxn]; int query(int u, int v, int k) { int root = LCA(u, v); int ans ; int i, j; // cout << deg[u] << " " << deg[root] << endl; if(deg[u] - deg[root] + 1 >= k) { ans = deg[u] - k + 1; for(i = 0; (1 << i) <= deg[u]; i++); i--; for(j = i; j >= 0; j--) { if(deg[u] - (1 << j) >= ans) { u = fa[u][j]; } } return u; } else { ans = deg[root] + k - (deg[u] - deg[root] + 1); cout << ans << endl; for(i = 0; (1 << i) <= deg[v]; i++); i--; for(j = i; j >= 0; j--) { if(deg[v] - (1 << j) >= ans) { v = fa[v][j]; } } return v; } } int main() { int T; scanf("%d", &T); while(T--) { int n; scanf("%d", &n); int u, v, w; memset(flag, false, sizeof(flag)); init(); for(int i = 0; i < n - 1; i++) { scanf("%d %d %d", &u, &v, &w); addedge(u, v, w); addedge(v, u, w); flag[v] = true; } int root; for(int i = 1; i <= n; i++) { if(!flag[i]) { root = i; break; } } bfs(root); char ch[15]; int uu, vv, ww; while(1) { scanf("%s", ch); if(strcmp(ch, "DONE") == 0) { break; } else if(strcmp(ch, "DIST") == 0) { scanf("%d %d", &uu, &vv); // cout << deg[uu] << " " << deg[vv] << endl; // cout << LCA(uu, vv) << ".......\n"; printf("%d\n", mmap[vv] + mmap[uu] - 2 * mmap[LCA(uu, vv)]); } else { scanf("%d %d %d", &uu, &vv, &ww); printf("%d\n", query(uu, vv, ww)); } } } return 0; }
标签:
原文地址:http://www.cnblogs.com/chenyang920/p/4827776.html