此页面通过工具从 csdn 导出,格式可能有问题。
testing...
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
const int maxn=10010;
const int maxm=maxn*2;
const int maxu=maxn*4;
const int maxt=maxn*10;
const int oo=1993101215;
int test,n,e,indexs,dep,tot,lca,debug;
int id;  //重链编号 
int node;  //线段树节点 
int pre[maxm],other[maxm],last[maxm],w[maxm]; //建树
int dfsq[maxu],f[maxu][20],g[maxu][20],depq[maxu],pos[maxn];  //LCA相关 
int que[maxn],father[maxn],s[maxn],next[maxn],maxs[maxn],dis[maxn],a[maxn],fatherp[maxn];   //重链相关 
int left[maxt],right[maxt],leftnode[maxt],rightnode[maxt],root[maxn],data[maxt];   //线段树 
int pid[maxn];   //每个点所在的重链编号 
int order[maxn];  //每个点所在线段树的位置 
int ed[maxn];   //重链的结束节点
int link[maxn];  //节点上方的边是读入的第几条 
bool vis[maxn];
inline int MAX(int a,int b)
{
if (a>b)return a; else return b;
}
inline void add(int u,int v,int cost)
{
e++;
pre[e]=last[u];
last[u]=e;
other[e]=v;
w[e]=cost;
}
inline void init()
{
int i,u,v,cost;
memset(last,0,sizeof(last));
e=0;
scanf("%d\n",&n);
for (i=1;i<n;i++)
{
scanf("%d%d%d\n",&u,&v,&cost);
add(u,v,cost);
add(v,u,cost);
}    
}
inline void dfs(int u)
{
dfsq[++indexs]=u;
depq[indexs]=dep;
if (pos[u]==0) pos[u]=indexs;  //记录首次出现的位置
vis[u]=true;
for (int p=last[u];p;p=pre[p])
if (vis[other[p]]==false)
{
dep++;
dfs(other[p]);
dep–;
dfsq[++indexs]=u;
depq[indexs]=dep;
} 
}
inline void st()
{
//f[i][j]表示深搜序列i到j中最小的深度值
//g[i][j]表示深度值最小的节点编号
int i,j;
for (i=1;i<=indexs;i++)
{
f[i][0]=depq[i];
g[i][0]=dfsq[i];
}
for (j=1;j<=int(log(indexs)/log(2));j++)
for (i=1;i<=indexs-(1<<j)+1;i++)
if (f[i][j-1]>f[i+(1<<(j-1))][j-1])
{
f[i][j]=f[i+(1<<(j-1))][j-1];
g[i][j]=g[i+(1<<(j-1))][j-1];                           
}
else
{
f[i][j]=f[i][j-1];
g[i][j]=g[i][j-1]; 
}
}
inline void getlca()
{
indexs=0;
dep=1;
memset(vis,0,sizeof(vis));
memset(pos,0,sizeof(pos));
dfs(1);
st(); 
}
inline int rmq(int x0,int y0)
{
int l,r,t,k;
l=pos[x0];
r=pos[y0];
if (l>r) {t=l;l=r;r=t;}
k=int(log(r-l+1)/log(2));
if (f[l][k]<f[r-(1<<k)+1][k])
return g[l][k];
else
return g[r-(1<<k)+1][k];
}
inline void build(int l,int r,int &t)
{
if (t==0)  t=++node;
int mid=(l+r)/2;
left[t]=l;
right[t]=r;
if (l==r)
{
data[t]=w[fatherp[a[l]]];
return;     
}
build(l,mid,leftnode[t]);
build(mid+1,r,rightnode[t]);
data[t]=MAX(data[leftnode[t]],data[rightnode[t]]);
}
inline int find(int l,int r,int t)
{
if ((l==left[t])&&(r==right[t])) return data[t];
int mid=(left[t]+right[t])/2;
if (r<=mid) return find(l,r,leftnode[t]);
if (l>=mid+1) return find(l,r,rightnode[t]);
return MAX(find(l,mid,leftnode[t]),find(mid+1,r,rightnode[t])); 
}
inline void change(int x,int v,int t)
{
if (left[t]==right[t])
{
data[t]=v;
return ;
}
int mid=(left[t]+right[t])/2;
if (x<=mid)
change(x,v,leftnode[t]);
if (x>=mid+1)
change(x,v,rightnode[t]);
data[t]=MAX(data[leftnode[t]],data[rightnode[t]]);
}
inline void bfs()  //求重链
{
int i,j,l,r,q,p;
memset(vis,0,sizeof(vis));
memset(maxs,0,sizeof(maxs));
memset(link,0,sizeof(link));
memset(next,0,sizeof(next));
node=0; id=0;
memset(root,0,sizeof(root));
memset(leftnode,0,sizeof(leftnode));
memset(rightnode,0,sizeof(rightnode));
memset(dis,0,sizeof(dis));
memset(order,0,sizeof(order));
memset(pid,0,sizeof(pid));
memset(ed,0,sizeof(ed));
memset(father,0,sizeof(father));
memset(left,0,sizeof(left));
memset(right,0,sizeof(right));
memset(data,0,sizeof(data));
l=0;
r=1;
que[r]=1;
vis[1]=true;
dis[1]=1;       //维护深度 
while (l<r)
{
     q=que[++l];
     for (p=last[q];p;p=pre[p])
         if (vis[other[p]]==false)
         {
             vis[other[p]]=true;
             que[++r]=other[p]; 
             father[other[p]]=q;           //求得他的父亲节点编号   
             fatherp[other[p]]=p;          //当前节点到父亲的边
             dis[other[p]]=dis[q]+1;
             link[(p+1)/2]=other[p];
         }
}
for (i=1;i<=n;i++) s[i]=1;
for (i=n;i;i--) s[father[que[i]]]+=s[que[i]];
for (i=1;i<=n;i++)
{
    q=que[i];
    for (p=last[q];p;p=pre[p])
        if (dis[q]<dis[other[p]])
            if (s[other[p]]>maxs[q])
            {
                maxs[q]=s[other[p]];
                next[q]=other[p];
            }
}
memset(vis,0,sizeof(vis));
for (i=1;i<=n;i++)
{
    q=que[i];
    if (vis[q]==true) continue;
    id++;
    tot=0;
    ed[id]=q; 
    do
    {
          a[++tot]=q;
          vis[q]=true;
          pid[q]=id;
          order[q]=tot;
          q=next[q];      
    }   
    while (q!=0);
    build(1,tot,root[id]);
}
/*if (debug==2)
    for (i=1;i<=n;i++)
        if (dis[i]<dis[ed[pid[i]]])  
             printf("?");*/
}
inline int ask(int x,int y)   //从x节点一直到祖先y
{
int ans=-oo;
//if (dt==1) printf("%d %d\n",x,y);
while (x!=y)
{
//if (dt==1) printf(“x : %d %d %d %d\n”,x,y,dis[x],dis[y]);
if (dis[ed[pid[x]]]<=dis[y])  //如果在一条链上
{
ans=MAX(ans,find(order[y]+1,order[x],root[pid[x]]));
break;                     
}
if (dis[ed[pid[x]]]>dis[y])  //如果不在一条链上
{
ans=MAX(ans,find(1,order[x],root[pid[x]]));
//    if (dt==1) printf(“wo cao: %d %d\n”,dis[x],dis[father[ed[pid[x]]]]);
x=father[ed[pid[x]]];
continue;                     
}
}
return ans;
}
inline void work()
{
char s[30];
int x,y;
while (1)
{
    scanf("%s",s);
    if (s[0]=='D') break;
    if (s[0]=='C')
    {
        scanf("%d%d\n",&x,&y);     
        change(order[link[x]],y,root[pid[link[x]]]);              
    } 
    if (s[0]=='Q')
    {
        scanf("%d%d\n",&x,&y);
        lca=rmq(x,y);
        printf("%d\n",MAX(ask(x,lca),ask(y,lca)));
    }
    
}    
}
int main()
{
scanf("%d\n",&test);
while (test–)
{
debug++;
init();
getlca();
bfs();
work();
}
//system(“pause”);
return 0;
}