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

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

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

代码:

#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);elseupdate(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;
}

转载于:https://www.cnblogs.com/KirinSB/p/11211513.html

FZU 2082 过路费(树链剖分 边权)题解相关推荐

  1. POJ 3237.Tree -树链剖分(边权)(边值更新、路径边权最值、区间标记)贴个板子备忘...

    Tree Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 12247   Accepted: 3151 Descriptio ...

  2. 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释...

    P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...

  3. hdu 3966( 树链剖分+点权更新)

    题意:给一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路径上的所有点权值加上K D C1 C2 K:把C1与C2的路径上的所有点权值减去K Q C:查询节点编号为C ...

  4. 树链剖分边权模板spoj375

    树链剖分是树分解成多条链来解决树上两点之间的路径上的问题 如何求出树链:第一次dfs求出树上每个结点的大小和深度和最大的儿子,第二次dfs就能将最大的儿子串起来并hash(映射)到线段树上(或者其他数 ...

  5. hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询

    点权树的模板题,另外发现树状数组也是可以区间更新的.. 注意在对链进行操作时方向不要搞错 线段树版本 #include<bits/stdc++.h> using namespace std ...

  6. BZOJ 2157 「国家集训队」旅游(树链剖分,线段树,边权转点权)【BZOJ计划】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2157 是 hydro 的 BZOJ ...

  7. [ZJOI2015] 幻想乡战略游戏(树链剖分 + 线段树二分 + 带权重心)

    problem luogu-P3345 solution 这是一个带权重心的题,考察动态点分治.点分治?呵,不可能的,这辈子都不可能写点分治 我们重新考虑重心的性质:以这个点为根时,所有子树的大小不会 ...

  8. FZU 2082 过路费

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

  9. 树链剖分入门——[kuangbin]树链剖分

    树链剖分的本质就是将一棵树拆分成一段一段连续的区间,然后放在一起就可以用一棵单独的线段树处理区间问题,只需要将树上节点和线段树节点的对应关系求好就可以很方便的互相转换,而树上两点之间路径的相关问题就可 ...

  10. P1505 [国家集训队]旅游 树链剖分

    题目链接 题意:树上更新某一点权值,更新两点简单路径权值,查询最大,最小,和 思路:思路应该比较简单,就是树链剖分后用线段树维护区间最大最小以及区间和. 但是本题比较特殊的是给的边权,转化为点权即可. ...

最新文章

  1. java juc exchanger_JUC工具类实例
  2. 常用的几种简单的内部排序方法
  3. web前端模块化开发_真正的模块化Web应用程序:为什么没有开发标准?
  4. [Java基础][Java]toString()方法
  5. java nio有哪些功能_如何真正理解java中的NIO?
  6. 信息与数据科学国际会议征文通知
  7. nslookup 使用说明
  8. 传输层学习之五(TCP的SACK,F-RTO)
  9. 虚拟机安装Centos 7网上教程整合
  10. 传奇开服很难吗?教你怎么给Hero传奇引擎添加NPC
  11. 小米手机切换应用--完美实现步骤
  12. 最全的程序化交易模型设计思路在这里
  13. Android Studio BMI计算器设计(三种计算标准)
  14. matplotlib:使用emoji字体实现简易象形图
  15. Ubuntu桌面出现Accept clipboard from viewers,Send clipboard to viewers,Send primary selection to vi等三行错误时
  16. 【安全服务】应急响应1:流程、排查与分析
  17. 报错ValueError: operands could not be broadcast together with shapes (448,448) with (224,224)
  18. 成功解决:Updates were rejected because the tip of your current branch is behind its remote...【解决方法】
  19. 在Linux系统中root密码忘记了怎么办?一招教会你
  20. 大数据之hadoop

热门文章

  1. FTP(持虚拟用户,并且每个虚拟用户可以具有独立的属性配置)
  2. String变量的两种创建方式
  3. api-gateway实践(01)服务网关 - 原型功能
  4. Zendframework 模块加载事件触发顺序。
  5. phpcms文章点击量统计方法
  6. Hibernate ehcache配置二级缓存及说明
  7. Hadoop2.2.0中HDFS的高可用性实现原理
  8. Windows 8 M2 Build 7955泄露下载
  9. cyhper study
  10. 网络唤醒无需任何软件,实现局域网广域网远程唤醒计算机