有n座城市,由n-1条路相连通,使得任意两座城市之间可达。每条路有过路费,要交过路费才能通过。每条路的过路费经常会更新,现问你,当前情况下,从城市a到城市b最少要花多少过路费。
Input
有多组样例,每组样例第一行输入两个正整数n,m(2 <= n<=50000,1<=m <= 50000),接下来n-1行,每行3个正整数a b c,(1 <= a,b <= n , a != b , 1 <= c <= 1000000000).数据保证给的路使得任意两座城市互相可达。接下来输入m行,表示m个操作,操作有两种:一. 0 a b,表示更新第a条路的过路费为b,1 <= a <= n-1 ; 二. 1 a b , 表示询问a到b最少要花多少过路费。
Output
对于每个询问,输出一行,表示最少要花的过路费。
Sample Input
2 3
1 2 1
1 1 2
0 1 2
1 2 1
Sample Output
1
Input
有多组样例,每组样例第一行输入两个正整数n,m(2 <= n<=50000,1<=m <= 50000),接下来n-1行,每行3个正整数a b c,(1 <= a,b <= n , a != b , 1 <= c <= 1000000000).数据保证给的路使得任意两座城市互相可达。接下来输入m行,表示m个操作,操作有两种:一. 0 a b,表示更新第a条路的过路费为b,1 <= a <= n-1 ; 二. 1 a b , 表示询问a到b最少要花多少过路费。
Output
对于每个询问,输出一行,表示最少要花的过路费。
Sample Input
2 3
1 2 1
1 1 2
0 1 2
1 2 1
Sample Output
1
2
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 10005
typedef long long ll;
int g[maxn];
struct node{
int to,nxt,vl;
}ed[maxn<<1];
int head[maxn],cnt;
void addedge(int u,int v,int vl){
ed[cnt].to=v;
ed[cnt].vl=vl;
ed[cnt].nxt=head[u];
head[u]=cnt++;
}
int sz[maxn],top[maxn],son[maxn],fa[maxn],p[maxn],dep[maxn];
int pos;
void dfs1(int u,int f,int d){
dep[u]=d;
sz[u]=1;
fa[u]=f;
for(int i=head[u];~i;i=ed[i].nxt){
int v=ed[i].to;
if(v==f)continue;
dfs1(v,u,d+1);
sz[u]+=sz[v];
if(son[u]==-1||sz[son[u]]<sz[v])son[u]=v;
}
}
void dfs2(int u,int tp){
top[u]=tp;
p[u]=pos++;
if(son[u]==-1)return;
dfs2(son[u],tp);
for(int i=head[u];~i;i=ed[i].nxt){
int v=ed[i].to;
if(v!=son[u]&&v!=fa[u]){
dfs2(v,v);
}
}
}
struct T{
int l,r;
ll sum;
}stu[maxn*4];
void pushup(int rt){
if(stu[rt].l==stu[rt].r)return ;
stu[rt].sum=stu[rt<<1].sum+stu[(rt<<1)+1].sum;
return ;
}
void build(int l,int r,int rt){
stu[rt].l=l,stu[rt].r=r;
if(l==r){
stu[rt].sum=g[l];
return ;
}
int mid=(l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,(rt<<1)+1);
pushup(rt);
return ;
}
void updata(int a,int b,int r){
if(stu[r].l==stu[r].r)
{stu[r].sum=b,g[a]=b;
return ;}
int mid=(stu[r].l+stu[r].r)>>1;
if(a>mid)updata(a,b,(r<<1)+1);
else updata(a,b,r<<1);
pushup(r);
return ;
}
ll q(int l,int r,int rt){
if(stu[rt].l==l&&stu[rt].r==r)return stu[rt].sum;
int mid=(stu[rt].l+stu[rt].r)>>1;
if(mid>=r)return q(l,r,rt<<1);
else if(mid<l)return q(l,r,(rt<<1)+1);
else return q(l,mid,rt<<1)+q(mid+1,r,(rt<<1)+1);
}
ll getsum(int u,int v){
int f1=top[u],f2=top[v];
ll ans=0;
while(f1!=f2){
if(dep[f1]<dep[f2]){
swap(f1,f2);
swap(u,v);
}
ans+=q(p[f1],p[u],1);
u=fa[f1];
f1=top[u];
}
if(u==v)return ans;
if(dep[u]<dep[v])swap(u,v);
ans+=q(p[son[v]],p[u],1);
return ans;
}
int uu[maxn];
void init(){
memset(head,-1,sizeof(head));
cnt=0;
memset(son,-1,sizeof(son));
pos=0;
}
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
init();
for(int i=1;i<n;i++){
int u,v,vl;
scanf("%d%d%d",&u,&v,&vl);
addedge(u,v,vl);
addedge(v,u,vl);
}
dfs1(1,0,0);
dfs2(1,1);
for(int i=0;i<cnt;i+=2){
int v=ed[i].to,vl=ed[i].vl;
int u=ed[i^1].to;
if(dep[u]<dep[v])swap(u,v);
g[p[u]]=vl;
uu[i/2+1]=u;
}
build(0,n-1,1);
while(m--){
int a,b,f;
scanf("%d%d%d",&f,&a,&b);
if(f==0){
updata(p[uu[a]],b,1);
}
else printf("%d\n",getsum(a,b));
}
}
return 0;
}