view code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int N = 10010;
const int INF = 1<<30;
int _, n, pre[N], fa[N], sz[N], top[N];
int gid, dep[N], son[N], id[N], fid[N];
int Max[N<<2], Min[N<<2], neg[N<<2];
struct edge
{
int u, v, w, next;
edge() {}
edge(int u, int v,int w, int next):u(u),v(v),w(w),next(next) {}
}e[N<<1];
int ecnt;
inline void addedge(int u, int v, int w)
{
e[ecnt] = edge(u, v, w, pre[u]);
pre[u] = ecnt++;
e[ecnt] = edge(v, u, w, pre[v]);
pre[v] = ecnt++;
}
inline void dfs(int u, int f, int d)
{
sz[u]=1, fa[u]=f, dep[u]=d, son[u]=0;
for(int i=pre[u]; ~i; i=e[i].next)
{
int v = e[i].v;
if(v==f) continue;
dfs(v, u, d+1);
sz[u] += sz[v];
if(sz[son[u]]<sz[v]) son[u] = v;
}
}
inline void fxor(int &x)
{
x = x==INF?-INF:INF;
}
inline void getpos(int u, int f)
{
id[u] = ++gid;
fid[gid] = u;
top[u] = f;
if(son[u]==0) return ;
getpos(son[u], f);
for(int i=pre[u]; ~i; i=e[i].next)
{
int v = e[i].v;
if(v==fa[u] || v==son[u]) continue;
getpos(v, v);
}
}
inline void Up(int rt)
{
Max[rt] = max(Max[rt<<1], Max[rt<<1|1]);
Min[rt] = min(Min[rt<<1], Min[rt<<1|1]);
}
inline void build(int l, int r, int rt)
{
neg[rt] = Min[rt] = INF, Max[rt] = -INF;
if(l==r) return ;
int m = (l+r)>>1;
build(lson);
build(rson);
}
inline void Down(int rt)
{
if(neg[rt]==-INF)
{
int ls=rt<<1, rs=ls|1;
fxor(neg[ls]), fxor(neg[rs]);
Min[ls] = -Min[ls];
Max[ls] = -Max[ls];
swap(Max[ls], Min[ls]);
Min[rs] = -Min[rs];
Max[rs] = -Max[rs];
swap(Max[rs], Min[rs]);
neg[rt] = INF;
}
}
inline void update(int L, int R, int c, int l, int r, int rt)
{
if(L<=l && R>=r){
if(c>-INF) Min[rt] = Max[rt] = c;
else{
fxor(neg[rt]);
Min[rt] = -Min[rt];
Max[rt] = -Max[rt];
swap(Min[rt], Max[rt]);
}
return ;
}
Down(rt);
int m = (l+r)>>1;
if(L<=m) update(L, R, c, lson);
if(R>m) update(L, R, c, rson);
Up(rt);
}
inline int query(int L, int R, int l, int r, int rt)
{
if(L<=l && r<=R) return Max[rt];
Down(rt);
int m = (l+r)>>1;
int ans = -INF;
if(L<=m) ans = max(ans, query(L, R, lson));
if(R>m) ans = max(ans, query(L, R, rson));
return ans;
}
inline int lcaQ(int u, int v, bool flag)
{
int fu=top[u], fv=top[v];
int ans = -INF;
while(fv!=fu)
{
if(dep[fu]<dep[fv])
{
swap(fv, fu); swap(u, v);
}
if(flag) ans = max(ans,query(id[fu], id[u], 1, gid, 1));
else update(id[fu], id[u], -INF, 1, gid, 1);
u = fa[fu];
fu = top[u];
}
if(dep[u]<dep[v]) swap(u,v);
if(u!=v)
{
if(flag) ans = max(ans, query(id[v]+1, id[u], 1, gid, 1));
else update(id[v]+1, id[u], -INF, 1, gid, 1);
}
return ans;
}
inline void solve()
{
ecnt = 0, gid = 0;
memset(pre, -1, sizeof(pre));
scanf("%d", &n);
int u, v, w;
for(int i=1; i<n; i++)
{
scanf("%d%d%d", &u, &v, &w);
addedge(u, v, w);
}
sz[0] = 0;
dfs(1, 1, 0);
getpos(1, 1);
build(1, gid , 1);
for(int i=1; i<ecnt; i+=2)
{
if(dep[e[i].u] < dep[e[i].v]) swap(e[i].u, e[i].v);
update(id[e[i].u], id[e[i].u], e[i].w, 1, gid, 1);
}
char str[15];
while(scanf("%s", str)>0 && str[0]!=‘D‘)
{
scanf("%d%d", &u, &v);
if(str[0]==‘Q‘)
printf("%d\n",lcaQ(u, v, 1));
else if(str[0]==‘N‘)
lcaQ(u, v, 0);
else
update(id[e[2*u-1].u], id[e[2*u-1].u], v, 1, gid, 1);
}
}
int main()
{
// freopen("in.txt", "r", stdin);
cin>>_;
while(_--) solve();
return 0;
}