Accept: 875    Submit: 2839
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

Source

FOJ有奖月赛-2012年4月(校赛热身赛)

 
思路:树链剖分
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int sigma_size=;
const int N=+;
const int MAXN=+;
const int inf=0x3fffffff;
const double eps=1e-;
const int mod=+;
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define PII pair<int, int>
#define mk(x,y) make_pair((x),(y))
int n,m,edge_cnt,cnt;
int head[MAXN],sz[MAXN],son[MAXN],fa[MAXN],top[MAXN],dep[MAXN],pos[MAXN];
struct Edge{
int u,v,w,next;
}edge[MAXN<<];
struct node{
int l,r;
ll sum;
}segtree[MAXN<<];
void init(){
edge_cnt=cnt=;
memset(head,-,sizeof(head));
}
void addedge(int u,int v,int w){
edge[edge_cnt].u=u;
edge[edge_cnt].v=v;
edge[edge_cnt].w=w;
edge[edge_cnt].next=head[u];
head[u]=edge_cnt++;
}
void dfs1(int u,int pre,int depth){
sz[u]=;
son[u]=;
dep[u]=depth;
fa[u]=pre;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(v == pre)
continue;
dfs1(v,u,depth+);
sz[u]+=sz[v];
if(sz[son[u]]<sz[v])
son[u]=v;
}
}
void dfs2(int u,int tp){
pos[u]=cnt++;
top[u]=tp;
if(son[u]!=)
dfs2(son[u],top[u]);
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(v == fa[u] || v == son[u])
continue;
dfs2(v,v);
}
}
void build(int rt,int l,int r){
segtree[rt].l=l;
segtree[rt].r=r;
segtree[rt].sum=;
if(l == r)
return ;
int mid=(l+r)>>;
build(L(rt),l,mid);
build(R(rt),mid+,r);
}
void push_up(int rt){
segtree[rt].sum=segtree[L(rt)].sum+segtree[R(rt)].sum;
}
void update(int rt,int p,int x){
if(segtree[rt].l == segtree[rt].r){
segtree[rt].sum=x;
return ;
}
int mid=(segtree[rt].l+segtree[rt].r)>>;
if(p<=mid)
update(L(rt),p,x);
else
update(R(rt),p,x);
push_up(rt);
}
ll query(int rt,int l,int r){
if(segtree[rt].l == l && segtree[rt].r == r)
return segtree[rt].sum;
int mid=(segtree[rt].l+segtree[rt].r)>>;
if(r<=mid)
return query(L(rt),l,r);
else if(l>mid)
return query(R(rt),l,r);
else
return query(L(rt),l,mid)+query(R(rt),mid+,r);
}
ll solve(int u,int v){
ll ans=;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])
swap(u,v);
ans+=query(,pos[top[u]],pos[u]);
u=fa[top[u]];
}
if(dep[u]>dep[v])
swap(u,v);
if(u!=v)
ans+=query(,pos[u]+,pos[v]);
return ans;
}
int main(){
while(~scanf("%d%d",&n,&m)){
init();
for(int i=;i<n;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
dfs1(,,);
dfs2(,);
build(,,n-);
for(int i=;i<edge_cnt;i+=){
int u=edge[i].u,v=edge[i].v,w=edge[i].w;
if(dep[u]<dep[v])
swap(u,v);
update(,pos[u],w);
}
for(int i=;i<m;i++){
int id,u,v;
scanf("%d",&id);
if(id == ){
int x,w;
scanf("%d%d",&x,&w);
x=(x-)*;
u=edge[x].u;
v=edge[x].v;
if(dep[u]<dep[v])
swap(u,v);
update(,pos[u],w);
}
else{
scanf("%d%d",&u,&v);
printf("%lld\n",solve(u,v));
}
}
}
}
 
 

FZU Problem 2082 过路费的更多相关文章

  1. Fzu Problem 2082 过路费 LCT,动态树

    题目:http://acm.fzu.edu.cn/problem.php?pid=2082 Problem 2082 过路费 Accept: 528    Submit: 1654Time Limit ...

  2. FZU Problem 2082 过路费 树链剖分

    Problem 2082 过路费    Problem Description 有n座城市,由n-1条路相连通,使得任意两座城市之间可达.每条路有过路费,要交过路费才能通过.每条路的过路费经常会更新, ...

  3. FZU oj Problem 2082 过路费

                                                                                    Problem 2082 过路费 Pro ...

  4. FOJ题目Problem 2082 过路费 (link cut tree边权更新)

    Problem 2082 过路费 Accept: 382    Submit: 1279 Time Limit: 1000 mSec    Memory Limit : 32768 KB Proble ...

  5. fzu 2082 过路费 (树链剖分+线段树 边权)

    Problem 2082 过路费 Accept: 887    Submit: 2881Time Limit: 1000 mSec    Memory Limit : 32768 KB  Proble ...

  6. FZU 2082 过路费(树链剖分)

    FZU 2082 过路费 题目链接 树链抛分改动边的模板题 代码: #include <cstdio> #include <cstring> #include <vect ...

  7. FZu Problem 2233 ~APTX4869 (并查集 + sort)

    题目链接: FZu Problem 2233 ~APTX4869 题目描述: 给一个n*n的矩阵,(i, j)表示第 i 种材料 和 第 j 种材料的影响值,这个矩阵代表这n个物品之间的影响值.当把这 ...

  8. FZu Problem 2236 第十四个目标 (线段树 + dp)

    题目链接: FZu  Problem 2236 第十四个目标 题目描述: 给出一个n个数的序列,问这个序列内严格递增序列有多少个?不要求连续 解题思路: 又遇到了用线段树来优化dp的题目,线段树节点里 ...

  9. 翻翻棋(找规律问题)(FZU Problem 2230)

    题目是这样的: FZU Problem 2230 象棋翻翻棋(暗棋)中双方在4*8的格子中交战,有时候最后会只剩下帅和将.根据暗棋的规则,棋子只能上下左右移动,且相同的级别下,主动移动到地方棋子方将吃 ...

随机推荐

  1. 包含utf8字符的 pickle 转 json的大坑处理过程

    背景:希望将pickle转换为json,由于pickle里有utf8的字符,因此转换失败. 转换代码如下: ''' Convert a pkl file into json file ''' impo ...

  2. bzoj 3598 [ Scoi 2014 ] 方伯伯的商场之旅 ——数位DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3598 数位DP...东看西看:http://www.cnblogs.com/Artanis/ ...

  3. (Go)05.基本数据类型和操作符

    保留的关键字段 1.Question1 package main import ( "fmt" ) func list(n int) { ; i <= n; i++ { fm ...

  4. PCB 生产周期计算逻辑与代码实现

    PCB生产周期计算逻辑: 代码实现: 调用代码: getWeek(DateTime.Now.Date, ); 周期计算逻辑: /// <summary> /// 获取周期 /// < ...

  5. js基本功能大全

    1.javascript的数组API: //定义数组 var pageIds = new Array(); pageIds.push('A'); 数组长度 pageIds.length; //shif ...

  6. Python 34(进程重点)

    一:开启进程的两种方式(*****) #开启进程的方式一: from multiprocessing import Process import time def task(name): print( ...

  7. HTML <!DOCTYPE>标签 各版本对应的标签是否有无

    参考来源: http://www.w3school.com.cn/tags/html_ref_dtd.asp HTML5/HTML 4.01/XHTML 元素和有效的 DTD 下面的表格列出了所有的 ...

  8. SVN 报错 sqlite[S11]: database disk image is malformed

    svn 提示数据库损坏 SVN 报错 sqlite[S11]: database disk image is malformed 解决办法:网上说的打开wc.db删除lock表 不管用.我发现这样可以 ...

  9. 关于EasyUI datagrid editor combogrid搜索框的实现

    首先需要datagrid editor对combogrid的扩展,这个是别人实现的: $.extend($.fn.datagrid.defaults.editors, { combogrid: { i ...

  10. MemcachedClient 使用说明

    上一篇介绍了Memcached基本使用方法<Memcached使用手册>,下面介绍java如何操作memcached.使用的是java_memcached-release_2.6.6. 一 ...