思路:边权转化到点权上,统一把每一条边的边权集中到深度较深的点上去。
#include<stdio.h> #include<iostream> #include<cstring> using namespace std; #define maxn 134567 struct edg { int v,to,w,u; } edge[maxn*2],in[maxn]; int n,q,cnt,sz,fa[maxn],head[maxn],s,ide,data[maxn]; int deep[maxn],siz[maxn],tree[maxn],u,v,w,typ,ans; int id_data[maxn],tid[maxn],top[maxn],son[maxn]; void add(int u,int v,int w) { edge[++ide].v=v; edge[ide].w=w; edge[ide].to=head[u]; head[u]=ide; } int lowbit(int x) { return x&(-x); } void updata(int x,int ad) { while(x<=n) { tree[x]+=ad; x+=lowbit(x); } } int query(int x) { int re=0; while(x>0) { re+=tree[x]; x-=lowbit(x); } return re; } void dfs1(int u,int pre,int op) { son[u]=-1,siz[u]=1; deep[u]=op,fa[u]=pre; for(int i=head[u]; i!=-1; i=edge[i].to) { int v=edge[i].v; if(v==pre)continue; dfs1(v,u,op+1); data[v]=edge[i].w; siz[u]+=siz[v]; if(son[v]==-1||siz[son[u]]<siz[v]) son[u]=v; } } void dfs2(int u,int tp) { top[u]=tp,tid[u]=++cnt; id_data[cnt]=data[u]; if(son[u]!=-1)dfs2(son[u],tp); for(int i=head[u]; i!=-1; i=edge[i].to) { int v=edge[i].v; if(v==fa[u]||v==son[u])continue; dfs2(v,v); } } void slove(int x,int y) { int tx=top[x],ty=top[y]; while(tx!=ty) { if(deep[tx]<deep[ty])swap(x,y),swap(tx,ty); ans+=query(tid[x])-query(tid[tx]-1); x=fa[tx],tx=top[x]; } if(deep[x]<deep[y])swap(x,y); ans+=query(tid[x])-query(tid[y]); } int main() { memset(head,-1,sizeof(head)); scanf("%d%d%d",&n,&q,&s); for(int i=1; i<n; i++) { scanf("%d%d%d",&u,&v,&w); in[i].u=u; in[i].v=v; in[i].w=w; add(u,v,w); add(v,u,w); } dfs1(1,0,1); dfs2(1,1); for(int i=1; i<=n; i++) updata(i,id_data[i]); while(q--) { scanf("%d",&typ); if(typ==0) { ans=0; scanf("%d",&u); slove(u,s); printf("%d\n",ans); s=u; } else { scanf("%d%d",&u,&v); if(deep[in[u].u]>deep[in[u].v]) u=in[u].u; else u=in[u].v; int xxx=query(tid[u])-query(tid[u]-1); v-=xxx; updata(tid[u],v); } } return 0; }