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. 在Android中创建文件

    import java.io.File; import java.io.IOException; import android.app.Activity; import android.os.Bund ...

  2. Android多级目录树

    本例中目录树的菜单数据是从json数据中获取,首先建立一个菜单实体类  MenuTree package com.gao.tree; /** * 菜单树的各级菜单实体类 * * @author tjs ...

  3. ride关键字

    定义变量:set variable 打印 :log 列表:create list 字符转数字型:evaluate 随机数:evaluate random.randint 日志截图:先导入screens ...

  4. Oracle_exp/expdp备份

    目录索引 1.exp和expdp的区别 2.expdp导出数据库流程 一.↓↓exp和expdp的区别↓↓ 1.exp和expdp最明显的区别就是导出速度的不同.expdp导出是并行导出(如果把exp ...

  5. iOS 代理设计模式

    在项目中经常会用到代理的设计模式,这是iOS中一种消息传递的方式,也可以通过这种方式传递一些参数. 在项目中,刚开始我是用一些代理来传递参数的,但是慢慢觉得代理的代码比较block多,所以就更多的使用 ...

  6. B - Lucky Division

    Problem description Petya loves lucky numbers. Everybody knows that lucky numbers are positive integ ...

  7. 导入不同业务数据通过Excel实现

    很多公司都用到了老系统移植到新系统,数据自然也需要迁移,这个解决方案之一就是使用Excel文件导入. 结合公司实现,然后简单写了个Demo. (PS:去找朋友本想着花几十分钟弄出来炫耀一波,结果花了三 ...

  8. 5.12redis

    Window配置Redis环境和简单使用 一.关于Redis Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理.它支持字符串.哈希表.列表.集合.有序 ...

  9. Asp.net MVC4 Step by Step (3)-数据验证

    ASP.NET MVC把数据验证集成到了请求处理过程中,控制器操作可以通过查询ModelState 来检查请求是否有效, 下面判断了ModelState的有效性后进行“保存或返回”操作.   [Htt ...

  10. 利用 html+css 画同心圆(concentric circles)——绝对布局与相对布局

    一.css 绘制圆 #circle { width: 300px; height: 300px; background-color: #000000; border-radius: 300px; } ...