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:

  • CHANGE i ti : change the cost of the i-th edge to ti
    or
  • QUERY a b : ask for the maximum edge cost on the path from node a to node b

Input

The first line of input contains an integer t, the number of test cases (t <= 20). 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 ab of cost c (c <= 1000000),
  • The next lines contain instructions "CHANGE i ti" or "QUERY a b",
  • The end of each test case is signified by the string "DONE".

There is one blank line between successive tests.

Output

For each "QUERY" operation, write one integer representing its result.

Example

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):

 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std; const int MAXN = ;
const int MAXE = * MAXN;
const int INF = 0x7fffffff; int head[MAXN], cost[MAXN], id[MAXN];
int weight[MAXE], to[MAXE], next[MAXE];
int n, ecnt; inline void init() {
memset(head, , sizeof(head));
ecnt = ;
} inline void add_edge(int u, int v, int c) {
to[ecnt] = v; weight[ecnt] = c; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; weight[ecnt] = c; next[ecnt] = head[v]; head[v] = ecnt++;
} int maxt[MAXN * ]; void modify(int x, int left, int right, int a, int b, int val) {
if(a <= left && right <= b) maxt[x] = val;
else {
int ll = x << , rr = ll ^ ;
int mid = (left + right) >> ;
if(a <= mid) modify(ll, left, mid, a, b, val);
if(mid < b) modify(rr, mid + , right, a, b, val);
maxt[x] = max(maxt[ll], maxt[rr]);
}
} int query(int x, int left, int right, int a, int b) {
if(a <= left && right <= b) return maxt[x];
else {
int ll = x << , rr = ll ^ ;
int mid = (left + right) >> , ret = ;
if(a <= mid) ret = max(ret, query(ll, left, mid, a, b));
if(mid < b) ret = max(ret, query(rr, mid + , right, a, b));
return ret;
}
} int size[MAXN], fa[MAXN], dep[MAXN], son[MAXN];
int tid[MAXN], top[MAXN], dfs_clock; void dfs_size(int u, int f, int depth) {
fa[u] = f; dep[u] = depth;
size[u] = ; son[u] = ;
int maxsize = ;
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(v == f) continue;
cost[v] = weight[p];
dfs_size(v, u, depth + );
size[u] += size[v];
if(size[v] > maxsize) {
maxsize = size[v];
son[u] = v;
}
}
} void dfs_heavy_edge(int u, int ancestor) {
tid[u] = ++dfs_clock; top[u] = ancestor;
modify(, , n, tid[u], tid[u], cost[u]);
if(son[u]) dfs_heavy_edge(son[u], ancestor);
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(v == fa[u] || v == son[u]) continue;
dfs_heavy_edge(v, v);
}
} int query(int x, int y) {
int ret = ;
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x, y);
ret = max(ret, query(, , n, tid[top[x]], tid[x]));
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
ret = max(ret, query(, , n, tid[x] + , tid[y]));
return ret;
} void change(int x, int y) {
int u = to[x], v = to[x ^ ];
if(fa[u] == v) swap(u, v);
modify(, , n, tid[v], tid[v], y);
} char str[]; int main() {
int T; scanf("%d", &T);
for(int t = ; t <= T; ++t) {
scanf("%d", &n);
init();
for(int i = ; i < n; ++i) {
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
id[i] = ecnt;
add_edge(u, v, c);
}
memset(maxt, , sizeof(maxt));
dfs_size(, , ); cost[] = -INF;
dfs_clock = ;
dfs_heavy_edge(, );
while(scanf("%s", str) && *str != 'D') {
int x, y;
scanf("%d%d", &x, &y);
if(*str == 'C') change(id[x], y);
else printf("%d\n", query(x, y));
}
}
}

代码(3400MS)(加了个IO优化……):

 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cctype>
using namespace std; const int MAXN = ;
const int MAXE = * MAXN;
const int INF = 0x7fffffff; int head[MAXN], cost[MAXN], id[MAXN];
int weight[MAXE], to[MAXE], next[MAXE];
int n, ecnt; inline void init() {
memset(head, , sizeof(head));
ecnt = ;
} inline void add_edge(int u, int v, int c) {
to[ecnt] = v; weight[ecnt] = c; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; weight[ecnt] = c; next[ecnt] = head[v]; head[v] = ecnt++;
} int maxt[MAXN * ]; void modify(int x, int left, int right, int a, int b, int val) {
if(a <= left && right <= b) maxt[x] = val;
else {
int ll = x << , rr = ll ^ ;
int mid = (left + right) >> ;
if(a <= mid) modify(ll, left, mid, a, b, val);
if(mid < b) modify(rr, mid + , right, a, b, val);
maxt[x] = max(maxt[ll], maxt[rr]);
}
} int query(int x, int left, int right, int a, int b) {
if(a <= left && right <= b) return maxt[x];
else {
int ll = x << , rr = ll ^ ;
int mid = (left + right) >> , ret = ;
if(a <= mid) ret = max(ret, query(ll, left, mid, a, b));
if(mid < b) ret = max(ret, query(rr, mid + , right, a, b));
return ret;
}
} int size[MAXN], fa[MAXN], dep[MAXN], son[MAXN];
int tid[MAXN], top[MAXN], dfs_clock; void dfs_size(int u, int f, int depth) {
fa[u] = f; dep[u] = depth;
size[u] = ; son[u] = ;
int maxsize = ;
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(v == f) continue;
cost[v] = weight[p];
dfs_size(v, u, depth + );
size[u] += size[v];
if(size[v] > maxsize) {
maxsize = size[v];
son[u] = v;
}
}
} void dfs_heavy_edge(int u, int ancestor) {
tid[u] = ++dfs_clock; top[u] = ancestor;
modify(, , n, tid[u], tid[u], cost[u]);
if(son[u]) dfs_heavy_edge(son[u], ancestor);
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(v == fa[u] || v == son[u]) continue;
dfs_heavy_edge(v, v);
}
} int query(int x, int y) {
int ret = ;
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x, y);
ret = max(ret, query(, , n, tid[top[x]], tid[x]));
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
ret = max(ret, query(, , n, tid[x] + , tid[y]));
return ret;
} void change(int x, int y) {
int u = to[x], v = to[x ^ ];
if(fa[u] == v) swap(u, v);
modify(, , n, tid[v], tid[v], y);
} char str[]; inline int readint() {
char c = getchar();
while(!isdigit(c)) c = getchar();
int ret = ;
while(isdigit(c)) ret = ret * + c - '', c = getchar();
return ret;
} int main() {
int T = readint();
for(int t = ; t <= T; ++t) {
n = readint();
init();
for(int i = ; i < n; ++i) {
int u = readint(), v = readint(), c = readint();
id[i] = ecnt;
add_edge(u, v, c);
}
memset(maxt, , sizeof(maxt));
dfs_size(, , ); cost[] = -INF;
dfs_clock = ;
dfs_heavy_edge(, );
while(scanf("%s", str) && *str != 'D') {
int x = readint(), y = readint();
if(*str == 'C') change(id[x], y);
else printf("%d\n", query(x, y));
}
}
}

最新文章

  1. mysql技术点1.-----------查询当天的所有数据
  2. 项目游戏开发日记 No.0x000004
  3. [转]EntityFramework状态变化AutoDetectChangesEnabled与SaveChanged参数说明
  4. 用JavaScript输出表格
  5. webpack+react配置
  6. Instant Run
  7. 【leetcode】Find Peak Element ☆
  8. InstallShield12豪华版破解版下载|InstallShield下载|软件打包工具
  9. css学习--inline-block详解及dispaly:inline inline-block block 三者区别精要概括
  10. NAMESPACE
  11. MfC基础--绘图基础--win32
  12. css架构目标:预测,重用,扩展,维护
  13. poj 3172 Scales 搜索
  14. DataGrid 导出数据到 Excel
  15. Centos6.6上源码安装Nodejs V4版本
  16. Windows Server 2016-DHCP服务器审核日志大小调整
  17. Win10开机“提示语音”以及”随机播放音乐”
  18. QProcess与外部程序的调用
  19. phpstorm----------phpstorm如何安装和使用laravel plugin
  20. 使用lua实现99乘法口诀表,就这么简洁

热门文章

  1. mysql数据去重复distinct、group by
  2. Linux中软件使用笔记
  3. 基于 UIImagePickerController 的拓展封装 - iOS
  4. [vue warn]:typeError:_this.getMounted.forEach is not a function
  5. [HAOI2010]软件安装(树形背包,tarjan缩点)
  6. vector基础操作
  7. Eclipse关联tomcat
  8. 黑帽seo基础手法之快照劫持
  9. docker 启动 nginx 访问不了的问题
  10. pyqt5--学习资料