题目链接:https://vjudge.net/problem/SPOJ-QTREE
不错的Blog:
初学http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html
练习https://vjudge.net/contest/28982
练习https://oi.abcdabcd987.com/summary-of-heavy-light-decomposition/
SPOJ375
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define getmid int m=(c[rt].l+c[rt].r)>>1
using namespace std;
///基于边权,修改单条边
///查询路径边权最大值
const int maxn=10010;
int n;
struct Edge
{
int to,nxt;
}e[maxn*2];
struct segtree
{
int l,r;
int Max;
}c[maxn*4+5];
int head[maxn],ecnt;
int top[maxn];///top[v]表示v所在链的顶端结点
int fa[maxn]; ///父节点
int dep[maxn]; ///深度
int siz[maxn]; ///siz[v]表示以v为根的子树的结点树
int id[maxn];///id[v]表示v与其父节点的连边在线段树中的位置
int real[maxn]; ///表示线段树中的某个位置对应的边的起始编号
int son[maxn]; ///son[u]表示u的重儿子
int dfn;
int d[maxn][3];
void init()
{
ecnt=dfn=0;
memset(head,-1,sizeof(head));
memset(son,0,sizeof(son));
}
void add_edge(int u,int v)
{
e[++ecnt].nxt=head[u];
e[ecnt].to=v;
head[u]=ecnt;
}
void dfs1(int u,int f,int d)
{
int v;
dep[u]=d;
fa[u]=f;
siz[u]=1;
for(int i=head[u];i!=-1;i=e[i].nxt)
if((v=e[i].to)!=f)
{
dfs1(v,u,d+1);
siz[u]+=siz[v];
if(!son[u]||siz[son[u]]<siz[v])
son[u]=v;
}
}
void dfs2(int u,int tp)
{
int v;
top[u]=tp;
id[u]=++dfn;
real[id[u]]=u;
if(!son[u]) return;
dfs2(son[u],tp);
for(int i=head[u];i!=-1;i=e[i].nxt)
if((v=e[i].to)!=son[u]&&v!=fa[u])
dfs2(v,v);
}
void Build(int l,int r,int rt)
{
c[rt].l=l;
c[rt].r=r;
c[rt].Max=0;
if(l==r) return;
int m=(l+r)>>1;
Build(l,m,rt<<1);
Build(m+1,r,rt<<1|1);
}
void Pushup(int rt)
{
c[rt].Max=max(c[rt<<1].Max,c[rt<<1|1].Max);
}
void Update(int rt,int k,int val)
{
if(c[rt].l==k&&c[rt].r==k)
{
c[rt].Max=val;
return;
}
getmid;
if(k<=m) Update(rt<<1,k,val);
else Update(rt<<1|1,k,val);
Pushup(rt);
}
int Query(int rt,int L,int R)
{
if(L<=c[rt].l&&R>=c[rt].r) return c[rt].Max;
getmid;
int ret=0;
if(L<=m) ret=max(ret,Query(rt<<1,L,R));
if(R>m) ret=max(ret,Query(rt<<1|1,L,R));
return ret;
}
int ask_e(int u,int v)
{
int f1,f2,tmp=0;
while((f1=top[u])!=(f2=top[v]))
{
if(dep[f1]<dep[f2])
{
swap(f1,f2);
swap(u,v);
}
tmp=max(tmp,Query(1,id[f1],id[u]));
u=fa[f1];
}
if(u==v) return tmp;
if(dep[u]>dep[v]) swap(u,v);
return max(tmp,Query(1,id[son[u]],id[v]));
}
int main()
{
int u,v;
int T;
cin>>T;
while(T--)
{
init();
cin>>n;
for(int i=1;i<=n-1;i++)
{
scanf("%d%d%d",&d[i][0],&d[i][1],&d[i][2]);
add_edge(d[i][0],d[i][1]);
add_edge(d[i][1],d[i][0]);
}
dfs1(1,0,1);
dfs2(1,1);
Build(1,dfn,1);
for(int i=1;i<=n-1;i++)
{
if(dep[d[i][0]]>dep[d[i][1]])
swap(d[i][0],d[i][1]);
Update(1,id[d[i][1]],d[i][2]);
}
char s[10];
while(scanf("%s",s))
{
if(s[0]=='D') break;
scanf("%d%d",&u,&v);
if(s[0]=='Q')
printf("%d\n",ask_e(u,v));
else Update(1,id[d[u][1]],v);
}
}
return 0;
}