模板
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <vector> using namespace std; #define lson (pos<<1) #define rson (pos<<1|1) const int maxn = 100100; const int inf = 0x7fffffff; //----建边部分 struct Vector_edge//存vector用的东西 { int v, w; Vector_edge():v(0),w(0){} Vector_edge(int a, int b):v(a),w(b){} }; vector<Vector_edge>g[maxn]; struct edge { int to, next; }e[maxn]; inline void add_edge(int a, int b, int c) { g[a].push_back(Vector_edge(b,c)); } //----树链部分===== int dfs_clock, cnt; struct node { int size, dep, son, top, fa, ti; node():size(0),dep(0),son(0),top(0),fa(0),ti(0){}; //size:v为跟节点数量 //dep:v的深度 根为1 //top:v所在链的顶端 //son:vv在同一重链的儿子节点,重儿子 //ti:v与父亲的连边,在线段树中的位置 }t[maxn]; void dfs_find(int u, int pa, int depth) { //cout<<u<<" "<<pa<<" "<<depth<<endl; t[u].son = 0; t[u].size = 1; t[u].dep = depth; t[u].fa = pa; for (int i = 0; i != g[u].size(); ++ i) { int v = g[u][i].v; if (v == pa) continue; dfs_find(v, u, depth + 1); t[u].size += t[v].size; //if (t[u].son == -1) t[u].son = v; if (t[v].size > t[t[u].son].size) t[u].son = v; } } void dfs_time(int u, int pa) { t[u].ti = ++ dfs_clock; t[u].top = pa; if (t[u].son != 0) dfs_time(t[u].son, t[u].top); for (int i = 0; i != g[u].size(); ++ i) { int v = g[u][i].v; if (v == t[u].son || v == t[u].fa) continue; dfs_time(v, v); } } //----线段树部分-- struct xianduan_node { int l,r,val,mx; int mid(){return (l+r)>>1;} }tree[maxn<<2]; void build(int pos, int l, int r) { tree[pos].l = l; tree[pos].r = r; tree[pos].mx = tree[pos].val = - inf; if (l == r) return; int mid = tree[pos].mid(); build(lson,l,mid); build(rson, mid + 1, r); } void update(int pos, int id, int w)// id改为w { if (tree[pos].l == tree[pos].r) { tree[pos].mx = tree[pos].val = w; return ; } int mid = tree[pos].mid(); if (mid >= id) update(lson, id, w); else update(rson, id, w); tree[pos].mx = max(tree[lson].mx, tree[rson].mx); } int query(int pos, int L, int R) { //cout<<L<<" "<<R<<" "<<pos<<" "<<tree[pos].l<<" "<<tree[pos].r<<" "<<tree[pos].mx<<endl; if (L <= tree[pos].l && tree[pos].r <= R) return tree[pos].mx; int mid = tree[pos].mid(); int ans = - inf; if (mid >= L) ans = max(ans, query(lson, L, R)); if (mid < R) ans = max(ans, query(rson, L, R)); return ans; } int lca(int x, int y) { int ans = -inf; while (t[x].top != t[y].top) { if (t[t[x].top].dep < t[t[y].top].dep) swap(x,y); ans = max(ans, query(1, t[t[x].top].ti, t[x].ti)); x = t[t[x].top].fa; } if (t[x].dep > t[y].dep) swap(x, y); //cout<<x<<" "<<y<<endl; //cout<<ans<<endl; //cout<<t[x].ti<<" "<<t[y].ti<<endl; //cout<<endl<<endl; if (x != y) ans = max(ans , query(1, t[x].ti + 1, t[y].ti)); ////这里的t[x].ti指的是x与其父亲的边,所以一定注意+1 return ans; } int n; int da[maxn][3]; void clear() { cnt = dfs_clock = 0; for (int i = 0; i != maxn; ++ i) g[i].clear(); } int main() { int T; scanf("%d", &T); while (T--) { clear(); scanf("%d", &n); for (int i = 1; i < n; ++ i) { scanf("%d%d%d", &da[i][0], &da[i][1], &da[i][2]); add_edge(da[i][0], da[i][1], da[i][2]); add_edge(da[i][1], da[i][0], da[i][2]); } dfs_find(1, 1, 1); dfs_time(1, 1); build(1, 2, n);//因为1没有前驱边,1是树根 for (int i = 1; i < n; i ++ ) { if (t[da[i][0]].dep > t[da[i][1]].dep) swap(da[i][0] , da[i][1]); update(1, t[da[i][1]].ti, da[i][2]); } char he[100]; while(1) { scanf("%s",he); if(he[0]=='D')break; if(he[0]=='Q') { int a,b;scanf("%d%d",&a,&b); printf("%d\n",lca(a,b)); } else { int a,b;scanf("%d%d",&a,&b); update(1,t[da[a][1]].ti,b); } } printf("\n"); } return 0; } /* 1 5 1 2 3 1 3 1 3 4 3 1 5 3 QUERY 1 4 DONE */