题意:给出每条边权值,可以更新每条边权值,询问两个点路径的最小权值

思路:重链剖分边权化点权,让每个儿子节点继承边权。

插点权的时候比较边的两个节点的深度,插进儿子节点中。

代码:

#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 50000 + 5;
const int M = 50 + 5;
const ull seed = 131;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
int fa[maxn];
int top[maxn];
int sz[maxn];
int son[maxn];
int deep[maxn];
int dfn[maxn], tol;
int fd[maxn]; int n, m;
struct Edge{
int v, w, id, next;
}edge[maxn << 1];
int head[maxn], tot;
void init(){
memset(head, -1, sizeof(head));
tot = tol = 0;
memset(son, -1, sizeof(son));
}
void addEdge(int u, int v, int w, int id){
edge[tot].v = v;
edge[tot].w = w;
edge[tot].id = id;
edge[tot].next = head[u];
head[u] = tot++;
}
void dfs1(int u, int pre, int d){
deep[u] = d;
fa[u] = pre;
sz[u] = 1;
for(int i = head[u]; i != -1; i = edge[i].next){
int v = edge[i].v;
if(v == pre) continue;
dfs1(v, u, d + 1);
sz[u] += sz[v];
if(son[u] == -1 || sz[v] > sz[son[u]])
son[u] = v;
}
}
void dfs2(int u, int tp){
top[u] = tp;
dfn[u] = ++tol;
fd[tol] = u;
if(son[u] == -1) return;
dfs2(son[u], tp);
for(int i = head[u]; i != -1; i = edge[i].next){
int v = edge[i].v;
if(v != son[u] && v != fa[u]){
dfs2(v, v);
}
}
} ll sum[maxn << 2];
void update(int pos, int l, int r, int v, int rt){
if(l == r){
sum[rt] = v;
return;
}
int m = (l + r) >> 1;
if(pos <= m)
update(pos, l, m, v, rt << 1);
else
update(pos, m + 1, r, v, rt << 1 | 1);
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
ll query(int L, int R, int l, int r, int rt){
if(L <= l && R >= r){
return sum[rt];
}
int m = (l + r) >> 1, ans = 0;
if(L <= m)
ans += query(L, R, l, m, rt << 1);
if(R > m)
ans += query(L, R, m + 1, r, rt << 1 | 1);
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
return ans;
} ll change(int u, int v){
ll ret = 0;
while(top[u] != top[v]){
if(deep[top[u]] < deep[top[v]]) swap(u, v);
ret += query(dfn[top[u]], dfn[u], 1, n, 1);
u = fa[top[u]];
}
if(u == v) return ret; //!!!
if(deep[u] > deep[v]) swap(u, v);
ret += query(dfn[son[u]], dfn[v], 1, n, 1);
return ret;
}
int e[maxn][3];
int main(){
while(~scanf("%d%d", &n, &m)){
init();
for(int i = 1; i <= n - 1; i++){
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
addEdge(u, v, w, i);
addEdge(v, u, w, i);
e[i][0] = u, e[i][1] = v, e[i][2] = w;
}
dfs1(1, 0, 0);
dfs2(1, 1);
for(int i = 1; i <= n - 1; i++){
int fx = e[i][0], fy = e[i][1];
if(deep[fx] < deep[fy]) swap(fx, fy);
update(dfn[fx], 1, n, e[i][2], 1);
}
while(m--){
int op, a, b;
scanf("%d%d%d", &op, &a, &b);
if(op == 0){
int fx = e[a][0], fy = e[a][1];
if(deep[fx] < deep[fy]) swap(fx, fy);
update(dfn[fx], 1, n, b, 1);
}
else{
printf("%lld\n", change(a, b));
}
}
}
return 0;
}

FZU 2082 过路费(树链剖分 边权)题解的更多相关文章

  1. FZU 2082 过路费 (树链剖分 修改单边权)

    题目链接:http://acm.fzu.edu.cn/problem.php?pid=2082 树链剖分模版题,求和,修改单边权. #include <iostream> #include ...

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

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

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

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

  4. BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...

  5. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

  6. POJ3237 Tree 树链剖分 边权

    POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...

  7. POJ2763 Housewife Wind 树链剖分 边权

    POJ2763 Housewife Wind 树链剖分 边权 传送门:http://poj.org/problem?id=2763 题意: n个点的,n-1条边,有边权 修改单边边权 询问 输出 当前 ...

  8. HDU3669 Aragorn's Story 树链剖分 点权

    HDU3669 Aragorn's Story 树链剖分 点权 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: n个点的,m条边,每个点都 ...

  9. BZOJ 1984: 月下“毛景树” [树链剖分 边权]

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1728  Solved: 531[Submit][Status][Discu ...

  10. SPOJ 375 (树链剖分 - 边权剖分 - 修改单边权)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/I 给你一棵有边权的树,有两个操作:一个操作是输出l到 ...

随机推荐

  1. [Ceoi2004]Journey

    题目描述 给出N个点,及你的出发点K. 接下来N-1行描述有关边的开始点,结束点,边长.保证图中不会有环 接下来给出数字J,代表你要走多少个点. 接下来J个数字,代表你要走过的点的编号.当然你可以自己 ...

  2. 三节锂电池充电管理芯片,IC电路图如何设计

    关于三节锂电池供电的产品,在三节锂电池上,需要三个电路系统: 1,三节锂电池保护电路, 2,三节锂电池充电电路, 3,三节锂电池输出电路. 1.三节锂电池保护电路,芯片电路图 控制三节锂电池池的充电电 ...

  3. 一个非常棒的Go-Json解析库

    json是一种数据格式,经常被用作数据交换,页面展示,序列化等场景,基本每种语言都有对应的json解析框架,Go语言也不例外,并且内置了json库,基本能够满足一些普通开发场景,但有些复杂场景下就不太 ...

  4. C# Twain协议调用扫描仪,设置多图像输出模式(Multi image output)

    Twain 随着扫描仪.数码相机和其他图像采集设备的引入,用户热切地发现了将图像整合到他们的文档和其他工作中的价值.然而,支持这种光栅数据的显示和操作成本很高,应用程序开发人员需要创建用户界面并内置设 ...

  5. Android N selectQualifiedNetwork分析

    前言: 参考:Android N wifi auto connect流程分析 后续 Android 8.0/9.0 wifi 自动连接评分机制 分析 前面说了,handleScanResults会去调 ...

  6. Promise用法

    1.概述 Promise是一步编程的一种解决方案,从语法上讲,promise是一个对象,从它可以获取异步的问题 Promise的优点: 可以避免多次异步调用嵌套导致的回调地域 提供了简洁的api,使得 ...

  7. 用tqdm和rich为固定路径和目标的python算法代码实现进度条

    适用场景 在存在固定长度的算法中可以可视化算法执行的过程,比如对一个固定长度的数组的遍历,就是一种适合使用进度条来进行可视化的场景.而一些条件循环,比如while循环,不一定适合使用进度条来对算法执行 ...

  8. 圣诞快乐!OIer挂分小技巧

    OIer常犯错误 自己的错误 循环里套return 线段树求和 int 定义,下传 int 定义 cmp<,>号分不清 主观行为举动错误 踢电源线,注意安全(_Destiny) TLE 大 ...

  9. java实现注销登录

    servlet HttpServletRequest request HttpSession session=request.getSession(); session.removeAttribute ...

  10. ModelArts 与HiLens Kit联合开发丨行人社交距离风险提示Demo

    摘要:本Demo使用YOLOv3_Resnet18模型来检测的视频流中的行人,获取行人坐标(即图中蓝色方框),然后计算所有检测到的人之间的相互"距离". 前情提要 听到行人社交距离 ...