0 a b,表示更新第a条路的过路费为b,1 <= a <= n-1 ;
1 a b , 表示询问a到b最少要花多少过路费。
对边操作,转化为对点的操作。 x - father[x] => a[] , 因为这条边是唯一的。
const int maxn = 50008 ; int n ; int siz[maxn] , top[maxn] , son[maxn] ; int dep[maxn] , tid[maxn] , fa[maxn] , rank[maxn] ; int head[maxn] , to[maxn*2] , next[maxn*2] , edge ; int tim ; void init(){ memset(head , -1 , sizeof(head)) ; memset(son , -1 , sizeof(son)) ; tim = edge = 0 ; } void addedge(int u , int v){ to[edge] = v , next[edge] = head[u] , head[u] = edge++ ; to[edge] = u , next[edge] = head[v] , head[v] = edge++ ; } void dfs1(int u , int father , int d){ dep[u] = d ; fa[u] = father ; siz[u] = 1 ; for(int i = head[u] ; i != -1 ; i = next[i]){ int v = to[i] ; if(v != father){ dfs1(v , u , d+1) ; siz[u] += siz[v] ; if(son[u] == -1 || siz[v] > siz[son[u]]) son[u] = v ; } } } void dfs2(int u , int tp){ top[u] = tp ; tid[u] = ++tim ; rank[tid[u]] = u ; if(son[u] == -1) return ; dfs2(son[u] , tp) ; for(int i = head[u] ; i != -1 ; i = next[i]){ int v = to[i] ; if(v != son[u] && v != fa[u]) dfs2(v , v) ; } } struct Line{ int u , v , w ; }line[maxn] ; LL a[maxn] , sum[maxn<<2] ; void up(int t){ sum[t] = sum[t<<1] + sum[t<<1|1] ; } void make(int l , int r , int t){ if(l == r){ sum[t] = a[l] ; return ; } int m = (l + r) >> 1 ; make(l , m , t<<1) ; make(m+1 , r , t<<1|1) ; up(t) ; } void update(int l , int r , int t , int x , LL c){ if(l == r){ sum[t] = c ; return ; } int m = (l + r) >> 1 ; if(x <= m) update(l , m , t<<1 , x , c) ; else update(m+1 , r , t<<1|1 , x , c) ; up(t) ; } LL ask(int L , int R , int l , int r , int t){ if(L <= l && r <= R) return sum[t] ; int m = (l + r) >> 1 ; LL s = 0 ; if(L <= m) s += ask(L , R , l , m , t<<1) ; if(R > m) s += ask(L , R , m+1 , r , t<<1|1) ; return s ; } LL change(int x , int y){ LL t = 0 ; while(top[x] != top[y]){ if(dep[top[x]] < dep[top[y]]) swap(x , y) ; t += ask(tid[top[x]] , tid[x] , 1 , n , 1) ; x = fa[top[x]] ; } if(x == y) return t ; if(dep[x] > dep[y]) swap(x , y) ; t += ask(tid[x] + 1 , tid[y] , 1 , n , 1) ; // 注意是 tid[x] + 1 return t ; } int main(){ int m , i , k , l , r ; memset(a , 0 , sizeof(a)) ; while(scanf("%d%d" ,&n , &m) != EOF){ init() ; for(i = 1 ; i < n ; i++){ scanf("%d%d%d" ,&line[i].u , &line[i].v , &line[i].w) ; addedge(line[i].u , line[i].v) ; } dfs1(1 , 0 , 0) ; dfs2(1 , 1) ; for(i = 1 ; i < n ; i++){ if(tid[line[i].u] < tid[line[i].v]) swap(line[i].u , line[i].v) ; a[tid[line[i].u]] = LL(line[i].w) ; } make(1 , n , 1) ; while(m--){ scanf("%d%d%d" , &k , &l , &r) ; if(k == 0) update(1 , n , 1 , tid[line[l].u] , LL(r)) ; else printf("%I64d\n" , change(l , r)) ; } } return 0 ; }