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打算框架打完了再来补,结果打完发现只是区间加和单点查 前缀 ...
随机推荐
- python作业/练习/实战:生成随机密码
作业要求1.写一个函数,函数的功能是生成一批密码,存到文件里面 def gen_password(num): #num代表生成多少条密码2.密码复杂度要求 1)长度在,8-16位之间 2)密码必须包括 ...
- js添加onclick中自定义方法
最近写一个插件的时候遇到了这么一个问题. 插件的要求是,仅仅通过一行js代码,就需要生成相应的页面,不能改变源文件的代码 生成页面还好说,但是有一个问题就是,生成的页面中是有一个按钮的.按钮也是可以添 ...
- ajax 通过回调函数获取异步数据
这里不再解释什么是 ajax,以及什么是异步的问题. 我们直接来问题,这里采用 jQuery 的 ajax 方法来获取数据. 先来看代码: $(function () { let db = ''; $ ...
- oracle查询不显示小数点前的0
1.问题起源 oracle 数据库字段值为小于1的小数时,使用char类型处理,会丢失小数点前面的0 例如0.35就变成了.35 2.解决办法:用to_char函数格式化数字显 ...
- Vue.js实现一个SPA登录页面的过程【推荐】
地址:https://www.jb51.net/article/112550.htm vue路由跳转时判断用户是否登录功能的实现 地址:https://www.jb51.net/article/126 ...
- 使用IntelliJ IDEA配置Maven(详细操作)
一,下载Maven 进入官网http://maven.apache.org/ 点击Download 找到如下图所示的区域,注意你的操作系统. 点击安装你所需要的安装包,下载,解压. 二,Maven环 ...
- CentOS6.5下面OpenSSH低版本升级至7.3
升级前版本: openssl-1.0.1e-48.el6_8.1.x86_64 openssh-5.3p1-118.1.el6_8.x86_64 升级后版本: OpenSSL 1.0.2j OpenS ...
- 2018-8-10-WPF-播放-gif
title author date CreateTime categories WPF 播放 gif lindexi 2018-08-10 19:16:53 +0800 2018-2-13 17:23 ...
- 检查目录下 文件的权限-linux shell脚本
#!/bin/bash #History: #2019/07/23 Fsq #This Program will check Permissions on dir PATH=/bin:/sbin ...
- Red Hat 操作系统 rpm 卸载软件提示"error: %preun( ) scriptlet failed, exit status 1"
在linux里安装程序有两种方法,一种是源程序安装,按照安装包里的readme或者install文件指示,一步步地进行,通常是configure, make, install三部曲.另一种就是rpm包 ...