题目传送门
题目大意:给一个n个结点的树以及它的n-1条边,两个操作:1、更改其中的边权。2、询问结点a到b的路径中最大的边权值
有两篇讲得很好的博客
http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html
http://blog.csdn.net/y990041769/article/details/40348013
另外还有一篇论文:http://wenku.baidu.com/view/8861df38376baf1ffc4fada8
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define maxn 10005 #define lson i<<1,l,m #define rson i<<1|1,m+1,r struct Edge { int v,next; } edge[maxn<<1]; int tree[maxn],T, n, tot,cnt,a,b,e[maxn][3],head[maxn], dep[maxn], id[maxn], fa[maxn], top[maxn], son[maxn], num[maxn]; char s[10]; void add(int a, int b) { edge[++cnt].v = b; edge[cnt].next = head[a]; head[a] = cnt; } void dfs(int v) { num[v] = 1,son[v] = 0; for (int i = head[v]; i ; i = edge[i].next) if (edge[i].v != fa[v]) { fa[edge[i].v] = v; dep[edge[i].v] = dep[v]+1; dfs(edge[i].v); if (num[edge[i].v] > num[son[v]]) son[v] = edge[i].v; num[v] += num[edge[i].v]; } } void dfs2(int v, int tp) { id[v] = ++tot,top[v] = tp; if (son[v] != 0) dfs2(son[v], top[v]); for (int i = head[v]; i > 0; i = edge[i].next) if (edge[i].v != son[v] && edge[i].v != fa[v]) dfs2(edge[i].v, edge[i].v); } void update(int i, int l, int r, int k, int x) { if (k > r || l > k) return; if (l == r) { tree[i] = x; return; } int m = (l + r)>>1; update(lson, k, x); update(rson, k, x); tree[i] = max(tree[i<<1], tree[i<<1|1]); } int query(int i, int l, int r, int L, int R) { if (L> r || R < l) return 0; if (L<= l && r <= R) return tree[i]; int m = (l + r)>>1; return max(query(lson,L, R), query(rson, L,R)); } int find(int va, int vb) { int f1 = top[va], f2 = top[vb], ans = 0; while (f1 != f2) { if (dep[f1] < dep[f2]) { swap(f1, f2); swap(va, vb); } ans = max(ans, query(1, 1, tot, id[f1], id[va])); va = fa[f1]; f1 = top[va]; } if (va == vb) return ans; if (dep[va] > dep[vb]) swap(va, vb); return max(ans, query(1, 1, tot, id[son[va]], id[vb])); // } int main() { scanf("%d", &T); while(T--) { scanf("%d", &n); fa[1] = tot = dep[1] = cnt = 0; memset(num, 0, sizeof(num)); memset(head, 0, sizeof(head)); memset(tree, 0, sizeof(tree)); for (int i = 1; i < n; i++) { scanf("%d%d%d", &e[i][0], &e[i][1], &e[i][2]); add(e[i][0],e[i][1]); add(e[i][1],e[i][0]); } dfs(1); dfs2(1,1); for (int i = 1; i < n; i++) { if (dep[e[i][0]] > dep[e[i][1]]) swap(e[i][0], e[i][1]); update(1, 1, tot, id[e[i][1]], e[i][2]); } while(scanf("%s",s)==1) { if(s[0]=='D') break; scanf("%d%d",&a,&b); if(s[0]=='Q') printf("%d\n",find(a,b)); else update(1,1,tot,id[e[a][1]],b); } } return 0; }