Problem 2082 过路费

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=26;
const int N=100+50;
const int MAXN=50000+50;
const int inf=0x3fffffff;
const double eps=1e-8;
const int mod=100000000+7;
#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<<1];
struct node{int l,r;ll sum;
}segtree[MAXN<<2];
void init(){edge_cnt=cnt=0;memset(head,-1,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]=1; son[u]=0; dep[u]=depth; fa[u]=pre;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].v;if(v == pre)continue;dfs1(v,u,depth+1);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]!=0)dfs2(son[u],top[u]);for(int i=head[u];i!=-1;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=0;if(l == r)return ;int mid=(l+r)>>1;build(L(rt),l,mid); build(R(rt),mid+1,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)>>1;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)>>1;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+1,r);
}
ll solve(int u,int v){ll ans=0;while(top[u]!=top[v]){if(dep[top[u]]<dep[top[v]])swap(u,v);ans+=query(1,pos[top[u]],pos[u]);u=fa[top[u]];}if(dep[u]>dep[v])swap(u,v);if(u!=v)ans+=query(1,pos[u]+1,pos[v]);return ans;
}
int main(){while(~scanf("%d%d",&n,&m)){init();for(int i=1;i<n;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);addedge(u,v,w); addedge(v,u,w);}dfs1(1,1,1); dfs2(1,1); build(1,1,n-1);for(int i=0;i<edge_cnt;i+=2){int u=edge[i].u,v=edge[i].v,w=edge[i].w;if(dep[u]<dep[v])swap(u,v);update(1,pos[u],w);}for(int i=0;i<m;i++){int id,u,v;scanf("%d",&id);if(id == 0){int x,w;scanf("%d%d",&x,&w);x=(x-1)*2;u=edge[x].u; v=edge[x].v;if(dep[u]<dep[v])swap(u,v);update(1,pos[u],w);}else{scanf("%d%d",&u,&v);printf("%lld\n",solve(u,v));}}}
}

转载于:https://www.cnblogs.com/cangT-Tlan/p/8540375.html

FZU Problem 2082 过路费相关推荐

  1. FZU Problem 2238 Daxia Wzc's problem(Lucas定理求组合数)

    此文章可以使用目录功能哟↑(点击上方[+])  FZU Problem 2238 Daxia & Wzc's problem Accept: 0    Submit: 0 Time Limit ...

  2. FZU Problem 2221 RunningMan(思维考查)——第六届福建省大学生程序设计竞赛-重现赛

    此文章可以使用目录功能哟↑(点击上方[+])  FZU Problem 2221 RunningMan Accept: 0    Submit: 0 Time Limit: 1000 mSec     ...

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

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

  4. FZU Problem 2240 Daxia Suneast's problem(博弈+[单点更新,区间查询]线段树)

    此文章可以使用目录功能哟↑(点击上方[+])  FZU Problem 2240 Daxia & Suneast's problem Accept: 0    Submit: 0 Time L ...

  5. FZU Problem 2243 Daxia like uber(最短路)

    此文章可以使用目录功能哟↑(点击上方[+])  FZU Problem 2243 Daxia like uber Accept: 0    Submit: 0 Time Limit: 1000 mSe ...

  6. FZU 2082 过路费

    题目链接:http://acm.fzu.edu.cn/problem.php?pid=2082 题意: 有n座城市,由n-1条路相连通,使得任意两座城市之间可达.每条路有过路费,要交过路费才能通过.每 ...

  7. FZU - 2082 过路费

    树剖的裸题,中文题面所以就不多解释了,当然操作二,就是简单的求过路费之和,因为路径唯一,他的那个最少过路费我也是醉了. #include <iostream> #include <c ...

  8. 【计算几何】FZU Problem 2270 Two Triangles

    http://acm.fzu.edu.cn/problem.php?pid=2270 [题意] 给定6到10个点,从中选出6个不同的点组成两个三角形,使其中一个三角形可以通过另一个三角形平移和旋转得到 ...

  9. FZU Problem 2168 防守阵地 I

    http://acm.fzu.edu.cn/problem.php?pid=2168 题目大意: 给定n个数和m,要求从n个数中选择连续的m个,使得a[i]*1+a[i+1]*2+--a[i+m]*m ...

最新文章

  1. 矩阵奇异值分解简介及C++/OpenCV/Eigen的三种实现
  2. C/C++面试题目集锦
  3. VS2013_QT5.4_静态编译问题_已经解决
  4. 用DOS命令安装删除服务
  5. 网易云信集成视频教程(六):如何快速实现iOS下IM自定义消息收发?
  6. 简单的01背包和完全背包
  7. 2017西安交大ACM小学期数论 [完全平方数]
  8. python线程通信 消息传递_Python并发编程之线程消息通信机制/任务协调(四)
  9. 在wordpress中添加幻灯片展示
  10. linux oracle semopm,Linux 内核参数设置于详解 --Oracle 安装
  11. World of Warcraft .M2模型重建
  12. 调用虚拟内存编译时的error处理
  13. error LNK2019: 无法解析的外部符号 _WinMain@16
  14. MySql处理Unicode字符串
  15. HTTP 权威指南 阅读笔记
  16. 数据库系统及应用——班级管理系统
  17. MATLAB去除多余点的命令,如何清除matlab命令窗口中已有的内容
  18. kafka 精准一次性
  19. 【笔记】ThreadFactory自定义线程名前缀
  20. python实现金字塔图案

热门文章

  1. Openstack glance 安装 403错误
  2. AutoCAD 2023 入门与进阶
  3. red linux系统管理,Red hat Linux 系统管理篇
  4. 将md文件转化为html样式,在页面中进行渲染
  5. 公众号排名霸屏被动引流案例揭秘,是时候展示真正的技术了
  6. vue3 中通过$refs 获取子组件数据
  7. oracle复合索引的使用方法,ORACLE复合索引使用 注意事项
  8. 计算机代码新手入门教程,VJPAGE微简代码生成器新手快速入门教程
  9. linux curl d 用法,Linux下cURL使用教程之三:curl基本使用
  10. 求a+aa+aaa+aaa...a的值