hdu6393 /// 树链剖分
题目大意:
给定n q
在n个点n条边的图中
进行q次操作
0 k x 为修改第k条边的值为x
1 x y 为查询x到y的最短路
https://blog.csdn.net/nka_kun/article/details/81675119
用其中n-1条边构成一棵树 树链剖分
多出的那条边记录好 编号s 边的两端su sv 边权sw
此时两点间最短路为三种情况取小
树上x到y、树上x到su + 树上y到sv + sw、树上x到sv + 树上y到su + sw
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
#define mem(i,j) memset(i,j,sizeof(i))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define root 1,n,1
const int N=1e5+;
int n,q; struct QTree {
struct EDGE { int to,ne; }e[N<<];
int head[N], tot;
void add(int u,int v) {
e[tot].to=v;
e[tot].ne=head[u];
head[u]=tot++;
} int fa[N], son[N], dep[N], num[N];
int top[N], p[N], fp[N], pos; LL sumT[N<<]; void init() {
tot=; mem(head,);
pos=; mem(son,);
} // --------------------以下是线段树------------------------- void pushup(int rt) {
sumT[rt]=sumT[rt<<]+sumT[rt<<|];
}
void build(int l,int r,int rt) {
if(l==r) {
sumT[rt]=; return ;
}
int m=(l+r)>>;
build(lson), build(rson);
pushup(rt);
}
void update(int k,int w,int l,int r,int rt) {
if(l==r) {
sumT[rt]=w; return;
}
int m=(l+r)>>;
if(k<=m) update(k,w,lson);
else update(k,w,rson);
pushup(rt);
}
LL query(int L,int R,int l,int r,int rt) {
if(L<=l && r<=R) return sumT[rt];
int m=(l+r)>>; LL res=;
if(L<=m) res+=query(L,R,lson);
if(R>m) res+=query(L,R,rson);
return res;
} // --------------------以上是线段树------------------------- // --------------------以下是树链剖分------------------------- void dfs1(int u,int pre,int d) {
dep[u]=d; fa[u]=pre; num[u]=;
for(int i=head[u];i;i=e[i].ne) {
int v=e[i].to;
if(v!=fa[u]) {
dfs1(v,u,d+);
num[u]+=num[v];
if(!son[u] || num[v]>num[son[u]])
son[u]=v;
}
}
}
void dfs2(int u,int sp) {
top[u]=sp; p[u]=++pos; fp[p[u]]=u;
if(!son[u]) return;
dfs2(son[u],sp);
for(int i=head[u];i;i=e[i].ne) {
int v=e[i].to;
if(v!=son[u] && v!=fa[u])
dfs2(v,v);
}
}
LL queryPath(int x,int y) {
LL ans=;
int fx=top[x], fy=top[y];
while(fx!=fy) {
if(dep[fx]>=dep[fy]) {
ans+=query(p[fx],p[x],root);
x=fa[fx];
} else {
ans+=query(p[fy],p[y],root);
y=fa[fy];
}
fx=top[x], fy=top[y];
}
if(x==y) return ans;
if(dep[x]>dep[y]) swap(x,y);
return ans+query(p[son[x]],p[y],root);
} // --------------------以上是树链剖分------------------------- void initQTree() {
dfs1(,,);
dfs2(,);
build(root);
}
}T;
int E[N][];
int fa[N];
int getfa(int x) {
if(x==fa[x]) return x;
else return fa[x]=getfa(fa[x]);
} int main()
{
int t; scanf("%d",&t);
while(t--) {
scanf("%d%d",&n,&q);
T.init();
int s,su,sv,sw;
for(int i=;i<=n;i++) fa[i]=i;
for(int i=;i<=n;i++) {
int u,v,w; scanf("%d%d%d",&u,&v,&w);
E[i][]=u, E[i][]=v, E[i][]=w;
int fu=getfa(u), fv=getfa(v);
if(fu==fv) s=i,su=u,sv=v,sw=w;
else fa[fu]=fv,T.add(u,v),T.add(v,u);
}
T.initQTree();
for(int i=;i<=n;i++) {
if(i==s) continue;
if(T.dep[E[i][]]>T.dep[E[i][]])
swap(E[i][],E[i][]);
T.update(T.p[E[i][]],E[i][],root);
}
while(q--) {
int op; scanf("%d",&op);
if(op==) {
int k,w; scanf("%d%d",&k,&w);
if(k==s) sw=w;
else T.update(T.p[E[k][]],w,root);
} else {
int x,y; scanf("%d%d",&x,&y);
LL ans=sw+T.queryPath(x,su)+T.queryPath(sv,y);
ans=min(ans,sw+T.queryPath(x,sv)+T.queryPath(y,su));
ans=min(ans,T.queryPath(x,y));
printf("%lld\n",ans);
}
}
} return ;
}
hdu6393 /// 树链剖分的更多相关文章
- hdu6393 Traffic Network in Numazu 树链剖分
题目传送门 题意:给出n个点n条边的无向带权图,再给出两种操作,操作1是将第x条边的边权修改为y,操作2是询问点x到点y的最短路径. 思路:如果是n个点n-1条边,题目就变成了树,修改边权和询问最短路 ...
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
- BZOJ 1984: 月下“毛景树” [树链剖分 边权]
1984: 月下“毛景树” Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 1728 Solved: 531[Submit][Status][Discu ...
- codevs 1228 苹果树 树链剖分讲解
题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...
- 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)
题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...
- 树链剖分+线段树 CF 593D Happy Tree Party(快乐树聚会)
题目链接 题意: 有n个点的一棵树,两种操作: 1. a到b的路径上,给一个y,对于路径上每一条边,进行操作,问最后的y: 2. 修改某个条边p的值为c 思路: 链上操作的问题,想树链剖分和LCT,对 ...
- 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)
题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...
- bzoj2243树链剖分+染色段数
终于做了一道不是一眼出思路的代码题(⊙o⊙) 之前没有接触过这种关于染色段数的题目(其实上课好像讲过),于是百度了一下(现在思维能力好弱) 实际上每一段有用的信息就是总共有几段和两段各是什么颜色,在开 ...
- bzoj3631树链剖分
虽然是水题1A的感觉太爽了O(∩_∩)O~ 题意相当于n-1次树上路径上每个点权值+1,最后问每个点的权值 本来想写线段树,写好了change打算框架打完了再来补,结果打完发现只是区间加和单点查 前缀 ...
随机推荐
- 安装项目依赖pipreqs并生成requirements.txt
安装项目依赖:sudo pip3 install pipreqs 生成依赖文件(requirements.txt):pipreqs ./ # 进入项目目录,在项目文件夹里生成安装依赖文件里的环境: ...
- 基于MFC的Media Player播放器的控件方法和属性介绍
| 版权声明:本文为博主原创文章,未经博主允许不得转载. 因为使用第三方多媒体库或是第三方控件(Media Player)辅助播放,我们则必须要了解到Media Player控件的一些属性 和方法 ...
- 关于禁止微信端webapp内部下拉出现QQ浏览器的问题
<!DOCTYPE html> <html> <head> <title></title> </head> <style ...
- Optparse 简介
optparse 这个库的主要作用是可以用为脚本提供传递命令参数功能 一个简单的例子 def main(): parser = OptionParser(usage = "usage: %p ...
- Python-装饰器的进阶 小知识点
⼀. 通⽤装饰器的回顾 开闭原则: 对增加功能开放. 对修改代码封闭 装饰器的作⽤: 在不改变原有代码的基础上给⼀个函数增加功能 通⽤装饰器的写法: def wrapper(fn): def inne ...
- 装Windows和Linux双系统
Windows 7 + Linux mint 装来玩玩呗,好歹算是IT男 我电脑本来就是Windows 7 然后用软碟通做个Linux的启动盘 注意“便捷启动”要选syslinux 然后从U盘启动会进 ...
- 解决Redhat yum出现This system is not registered with RHN的方案
最近博主在学习Linux,菜鸟级别的的选手连装个Chrome都觉得难,悲了个催的……百度了很多教程,大多是类似的.博主的配置是在VM8下搭建的RHEL5.3 (Tikanga)版本,不知道什么原因,每 ...
- H5 IOS 虚拟键盘不回落的问题
在 H5 页面中,会发现在高版本的 IOS 系统中(ios12以上)和微信版本6.7.x以上,都会发现 input 等输入框,输入内容之后发现虚拟键盘消失,但是页面出现大面积白框. 解决办法(最后加上 ...
- Asp.net Controller中View 和Action方法认证Authorize 及对AuthorizeAttribute扩展
Asp.net Controller中View和Action方法认证Authorize 在建立Web 站点安全性时 1.登录后才可访问系统文件 ——限制 Forms认证 <authenticat ...
- Input标签文件上传,使用详解
1.html添加标签按钮 <button ion-button (click)="selectVideo()">添加</button> <input ...