You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.
We will ask you to perfrom some instructions of the following form:
The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.
For each test case:
There is one blank line between successive tests.
For each "QUERY" operation, write one integer representing its result.
Input: 1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE Output: 1 3
推荐论文:《树链剖分》:http://wenku.baidu.com/view/a088de01eff9aef8941e06c3.html
《QTREE解法的一些研究》:随便百度一下就有
思路:树链剖分,上面都讲得比较清楚了我就不讲了。对着树链剖分的伪代码写的,那个伪代码有一个错误(应该是错误吧……),询问那里应该是x = father[top[x]]。还有,在这题用线段树,点的权值记录与父节点的边的权值,那么最后的询问是要query(tid[x]+1, tid[y])
代码(3840MS):
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 7 const int MAXN = 10010; 8 const int MAXE = 2 * MAXN; 9 const int INF = 0x7fffffff; 10 11 int head[MAXN], cost[MAXN], id[MAXN]; 12 int weight[MAXE], to[MAXE], next[MAXE]; 13 int n, ecnt; 14 15 inline void init() { 16 memset(head, 0, sizeof(head)); 17 ecnt = 2; 18 } 19 20 inline void add_edge(int u, int v, int c) { 21 to[ecnt] = v; weight[ecnt] = c; next[ecnt] = head[u]; head[u] = ecnt++; 22 to[ecnt] = u; weight[ecnt] = c; next[ecnt] = head[v]; head[v] = ecnt++; 23 } 24 25 int maxt[MAXN * 4]; 26 27 void modify(int x, int left, int right, int a, int b, int val) { 28 if(a <= left && right <= b) maxt[x] = val; 29 else { 30 int ll = x << 1, rr = ll ^ 1; 31 int mid = (left + right) >> 1; 32 if(a <= mid) modify(ll, left, mid, a, b, val); 33 if(mid < b) modify(rr, mid + 1, right, a, b, val); 34 maxt[x] = max(maxt[ll], maxt[rr]); 35 } 36 } 37 38 int query(int x, int left, int right, int a, int b) { 39 if(a <= left && right <= b) return maxt[x]; 40 else { 41 int ll = x << 1, rr = ll ^ 1; 42 int mid = (left + right) >> 1, ret = 0; 43 if(a <= mid) ret = max(ret, query(ll, left, mid, a, b)); 44 if(mid < b) ret = max(ret, query(rr, mid + 1, right, a, b)); 45 return ret; 46 } 47 } 48 49 int size[MAXN], fa[MAXN], dep[MAXN], son[MAXN]; 50 int tid[MAXN], top[MAXN], dfs_clock; 51 52 void dfs_size(int u, int f, int depth) { 53 fa[u] = f; dep[u] = depth; 54 size[u] = 1; son[u] = 0; 55 int maxsize = 0; 56 for(int p = head[u]; p; p = next[p]) { 57 int &v = to[p]; 58 if(v == f) continue; 59 cost[v] = weight[p]; 60 dfs_size(v, u, depth + 1); 61 size[u] += size[v]; 62 if(size[v] > maxsize) { 63 maxsize = size[v]; 64 son[u] = v; 65 } 66 } 67 } 68 69 void dfs_heavy_edge(int u, int ancestor) { 70 tid[u] = ++dfs_clock; top[u] = ancestor; 71 modify(1, 1, n, tid[u], tid[u], cost[u]); 72 if(son[u]) dfs_heavy_edge(son[u], ancestor); 73 for(int p = head[u]; p; p = next[p]) { 74 int &v = to[p]; 75 if(v == fa[u] || v == son[u]) continue; 76 dfs_heavy_edge(v, v); 77 } 78 } 79 80 int query(int x, int y) { 81 int ret = 0; 82 while(top[x] != top[y]) { 83 if(dep[top[x]] < dep[top[y]]) swap(x, y); 84 ret = max(ret, query(1, 1, n, tid[top[x]], tid[x])); 85 x = fa[top[x]]; 86 } 87 if(dep[x] > dep[y]) swap(x, y); 88 ret = max(ret, query(1, 1, n, tid[x] + 1, tid[y])); 89 return ret; 90 } 91 92 void change(int x, int y) { 93 int u = to[x], v = to[x ^ 1]; 94 if(fa[u] == v) swap(u, v); 95 modify(1, 1, n, tid[v], tid[v], y); 96 } 97 98 char str[15]; 99 100 int main() { 101 int T; scanf("%d", &T); 102 for(int t = 1; t <= T; ++t) { 103 scanf("%d", &n); 104 init(); 105 for(int i = 1; i < n; ++i) { 106 int u, v, c; 107 scanf("%d%d%d", &u, &v, &c); 108 id[i] = ecnt; 109 add_edge(u, v, c); 110 } 111 memset(maxt, 0, sizeof(maxt)); 112 dfs_size(1, 0, 0); cost[1] = -INF; 113 dfs_clock = 0; 114 dfs_heavy_edge(1, 1); 115 while(scanf("%s", str) && *str != 'D') { 116 int x, y; 117 scanf("%d%d", &x, &y); 118 if(*str == 'C') change(id[x], y); 119 else printf("%d\n", query(x, y)); 120 } 121 } 122 }
代码(3400MS)(加了个IO优化……):
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <cctype> 6 using namespace std; 7 8 const int MAXN = 10010; 9 const int MAXE = 2 * MAXN; 10 const int INF = 0x7fffffff; 11 12 int head[MAXN], cost[MAXN], id[MAXN]; 13 int weight[MAXE], to[MAXE], next[MAXE]; 14 int n, ecnt; 15 16 inline void init() { 17 memset(head, 0, sizeof(head)); 18 ecnt = 2; 19 } 20 21 inline void add_edge(int u, int v, int c) { 22 to[ecnt] = v; weight[ecnt] = c; next[ecnt] = head[u]; head[u] = ecnt++; 23 to[ecnt] = u; weight[ecnt] = c; next[ecnt] = head[v]; head[v] = ecnt++; 24 } 25 26 int maxt[MAXN * 4]; 27 28 void modify(int x, int left, int right, int a, int b, int val) { 29 if(a <= left && right <= b) maxt[x] = val; 30 else { 31 int ll = x << 1, rr = ll ^ 1; 32 int mid = (left + right) >> 1; 33 if(a <= mid) modify(ll, left, mid, a, b, val); 34 if(mid < b) modify(rr, mid + 1, right, a, b, val); 35 maxt[x] = max(maxt[ll], maxt[rr]); 36 } 37 } 38 39 int query(int x, int left, int right, int a, int b) { 40 if(a <= left && right <= b) return maxt[x]; 41 else { 42 int ll = x << 1, rr = ll ^ 1; 43 int mid = (left + right) >> 1, ret = 0; 44 if(a <= mid) ret = max(ret, query(ll, left, mid, a, b)); 45 if(mid < b) ret = max(ret, query(rr, mid + 1, right, a, b)); 46 return ret; 47 } 48 } 49 50 int size[MAXN], fa[MAXN], dep[MAXN], son[MAXN]; 51 int tid[MAXN], top[MAXN], dfs_clock; 52 53 void dfs_size(int u, int f, int depth) { 54 fa[u] = f; dep[u] = depth; 55 size[u] = 1; son[u] = 0; 56 int maxsize = 0; 57 for(int p = head[u]; p; p = next[p]) { 58 int &v = to[p]; 59 if(v == f) continue; 60 cost[v] = weight[p]; 61 dfs_size(v, u, depth + 1); 62 size[u] += size[v]; 63 if(size[v] > maxsize) { 64 maxsize = size[v]; 65 son[u] = v; 66 } 67 } 68 } 69 70 void dfs_heavy_edge(int u, int ancestor) { 71 tid[u] = ++dfs_clock; top[u] = ancestor; 72 modify(1, 1, n, tid[u], tid[u], cost[u]); 73 if(son[u]) dfs_heavy_edge(son[u], ancestor); 74 for(int p = head[u]; p; p = next[p]) { 75 int &v = to[p]; 76 if(v == fa[u] || v == son[u]) continue; 77 dfs_heavy_edge(v, v); 78 } 79 } 80 81 int query(int x, int y) { 82 int ret = 0; 83 while(top[x] != top[y]) { 84 if(dep[top[x]] < dep[top[y]]) swap(x, y); 85 ret = max(ret, query(1, 1, n, tid[top[x]], tid[x])); 86 x = fa[top[x]]; 87 } 88 if(dep[x] > dep[y]) swap(x, y); 89 ret = max(ret, query(1, 1, n, tid[x] + 1, tid[y])); 90 return ret; 91 } 92 93 void change(int x, int y) { 94 int u = to[x], v = to[x ^ 1]; 95 if(fa[u] == v) swap(u, v); 96 modify(1, 1, n, tid[v], tid[v], y); 97 } 98 99 char str[15]; 100 101 inline int readint() { 102 char c = getchar(); 103 while(!isdigit(c)) c = getchar(); 104 int ret = 0; 105 while(isdigit(c)) ret = ret * 10 + c - '0', c = getchar(); 106 return ret; 107 } 108 109 int main() { 110 int T = readint(); 111 for(int t = 1; t <= T; ++t) { 112 n = readint(); 113 init(); 114 for(int i = 1; i < n; ++i) { 115 int u = readint(), v = readint(), c = readint(); 116 id[i] = ecnt; 117 add_edge(u, v, c); 118 } 119 memset(maxt, 0, sizeof(maxt)); 120 dfs_size(1, 0, 0); cost[1] = -INF; 121 dfs_clock = 0; 122 dfs_heavy_edge(1, 1); 123 while(scanf("%s", str) && *str != 'D') { 124 int x = readint(), y = readint(); 125 if(*str == 'C') change(id[x], y); 126 else printf("%d\n", query(x, y)); 127 } 128 } 129 }