FZU Problem 2082 過路費


 Problem 2082 過路費

Accept: 123    Submit: 499
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

有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

2



樹鏈剖分入門題。。

/*
 *=====================
 *File Name:a.cpp
 *Author: qqspeed
 *Date: 2014年 07月 18日 星期五 20:30:11 CST
 *=====================
 */
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#include <stdlib.h>
#include <algorithm>
using namespace std;

typedef long long ll;
#define rep(i,s,t) for(int i=s;i<t;i++)
#define red(i,s,t) for(int i=s-1;i>=t;i--)
#define ree(i,now) for(int i=head[now];i!=-1;i=edge[i].next)
#define clr(a,v) memset(a,v,sizeof a)
#define L t<<1
#define R t<<1|1
#define MID int mid=(l+r)>>1
#define max(a,b) (a<b?b:a)
#define min(a,b) (a<b?a:b)
#define SQR(a) ((a)*(a))

inline int input(){
	int ret=0;bool isN=0;char c=getchar();
	while(c<'0' || c>'9'){
		if(c=='-') isN=1;
		c=getchar();
	}
	while(c>='0' && c<='9'){
		ret=ret*10+c-'0';
		c=getchar();
	}
	return isN?-ret:ret;
}

inline void output(int x){    
    if(x<0){    
        putchar('-');x=-x;    
    }    
    int len=0,data[11];    
    while(x){    
        data[len++]=x%10;x/=10;    
    }    
    if(!len)    data[len++]=0;    
    while(len--)   
        putchar(data[len]+48);
    putchar('\n');  
} 

const int MAXN=50005;
int to[MAXN],w[MAXN],size[MAXN],son[MAXN],dep[MAXN],fa[MAXN],top[MAXN],cnt;
int n,m,a[MAXN],b[MAXN],c[MAXN];
int op,x,y;
int val[MAXN<<2];
struct EDGE{
	int v,next;
}edge[MAXN<<1];
int head[MAXN],e;

inline void addEdge(int u,int v){
	edge[e].v=v;
	edge[e].next=head[u]++;
	head[u]=e++;
}

inline void push(int t){
	val[t]=val[L]+val[R];
}

inline void build(int t,int l,int r){
	if(l==r) val[t]=w[l];
	else{
		MID;
		build(L,l,mid);build(R,mid+1,r);
		push(t);
	}
}

inline void add(int t,int l,int r,int x,int v){
	if(l==r) val[t]=v;
	else{
		MID;
		if(x<=mid) add(L,l,mid,x,v);
		else add(R,mid+1,r,x,v);
		push(t);
	}
}

inline int query(int t,int l,int r,int x,int y){
	if(l>=x && r<=y) return val[t];
	MID;
	if(y<=mid) return query(L,l,mid,x,y);
	else if(x>mid) return query(R,mid+1,r,x,y);
	else return query(L,l,mid,x,mid)+query(R,mid+1,r,mid+1,y);
}

inline void dfs1(int now,int pre){
	son[now]=0;
	size[now]=1;
	fa[now]=pre;
	dep[now]=dep[pre]+1;
	ree(i,now){
		int v=edge[i].v;
		if(v!=pre){
			dfs1(v,now);
			size[now]+=size[v];
			if(size[son[now]] < size[v]) son[now]=v;
		}
	}	
}

inline void dfs2(int now,int tp){
	top[now]=tp;
	to[now]=(++cnt);
	if(son[now]) dfs2(son[now],tp);
	ree(i,now){
		int v=edge[i].v;
		if(v!=son[now] && v!=fa[now]) dfs2(v,v);
	}
}

inline int Query(int a,int b){
	int f1=top[a],f2=top[b],ans=0;
	while(f1 != f2){
		if(dep[f1]<dep[f2]){
			swap(a,b),swap(f1,f2);
		}
		ans+=query(1,1,n,to[f1],to[a]);
		a=fa[f1];
		f1=top[a];
	}
	if(a==b) return ans;
	if(dep[a] > dep[b]) swap(a,b);
	return (ans+query(1,1,n,to[son[a]],to[b]));
}

int main(){
	while(~scanf("%d%d",&n,&m)){
		clr(head,-1),e=cnt=0;
		rep(i,1,n){
			a[i]=input(),b[i]=input(),c[i]=input();
			addEdge(a[i],b[i]),addEdge(b[i],a[i]);
		}
		size[0]=dep[0]=fa[0]=top[0]=son[0]=0;
		dfs1(1,1),dfs2(1,1);
		rep(i,1,n){
			if(dep[a[i]] < dep[b[i]]) swap(a[i],b[i]);
			a[i]=to[a[i]];
			w[a[i]]=c[i];
		}
		build(1,1,cnt);
		rep(i,0,m){
			op=input(),x=input(),y=input();
			if(op){
				output(Query(x,y));
			}
			else{
				x=a[x];
				add(1,1,n,x,y);
			}
		}
	}
	return 0;
}



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com