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打算框架打完了再来补,结果打完发现只是区间加和单点查 前缀 ...
随机推荐
- CMDB 调研报告
基础概念 1.什么是CMDB CMDB——配置管理数据库,通过识别.控制.维护,检查企业的IT资源,从而高效控制与管理不断变化的IT基础架构与IT服务,并为其它流程,例如事故管理.问题管理.变更管理. ...
- CFile CStdioFile CArchive 文件操作之异同(详细)
两者的主要区别: 一. CFile类操作文件默认的是Binary模式,CStdioFile类操作文件默认的是Text模式. 在Binary模式下我们必须输入'\r\n',才能起到回车换行的效果, ...
- sparkSQL获取DataFrame的几种方式
sparkSQL获取DataFrame的几种方式 1. on a specific DataFrame. import org.apache.spark.sql.Column df("col ...
- bootstrapTble 的一些小结
前言: 1.bootstrapTable 官网 http://bootstrap-table.wenzhixin.net.cn/zh-cn/ ,http://bootstrap-table.wenz ...
- 【总】.NET Core 2.0 详解
ASP.NET Core 认证与授权[7]:动态授权 雨夜朦胧 2017-11-24 11:21 阅读:7063 评论:19 ASP.NET Core 认证与授权[6]:授权策略是怎么执行的? 雨夜朦 ...
- buuctf zip伪加密
平时伪加密总是依赖osx,这道题无法直接解压,所以研究一下伪加密先放两张图(图是偷的)一般在压缩源文件数据区全局方式位标记处,真加密为 09 00,伪加密为00 00,而后面将压缩源文件目录区全局方式 ...
- python之命名元组的好处
collections.namedtuple() 命名元组的一个主要用途是将你的代码从下标操作中解脱出来举例使用 # 使用 from collections import namedtuple Sub ...
- 【记录】centOS 搭建logstash +docker搭建elasticsearch伪集群+kibana链接集群elasticsearch节点
[注意]本文主要用于自我记录,注释较少. 安装logstash 1.上传logstash-6.4.3.tar.gz到服务中 2.tar –zxvf logstash-6.4.3.tar.gz 3.cd ...
- android thread Runnable
原文链接: http://blog.csdn.net/boyupeng/article/details/6208072 这篇文章中有三点需要提前说明一下, 一: 在android中有两种实现线程thr ...
- ChainMap & python args parse
python的内建模块ChainMap可以把一组dict串起来并组成一个逻辑上的dict.ChainMap本身也是一个dict,但是查找的时候,会按照顺序在内部的dict依次查找. 什么时候使用Cha ...