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打算框架打完了再来补,结果打完发现只是区间加和单点查 前缀 ...
随机推荐
- Java输入/输出教程
Java输入/输出(I/O)处理从源读取数据并将数据写入目标.通常,读取存储在文件中的数据或使用I/O将数据写入到文件中. java.io和java.nio包中包含处理输入/输出的Java类.java ...
- 慎用margin系列3---IE6下3px bug
当我们想让一段文字出现在一个布局块的右边的时候,我们会让布局块向左浮动,然后把段落设置左布局块宽度大小的左空白.比如左布局块是.a{float:left;height: 110px;width: 28 ...
- UML指南系列——用例图
可以用用例来描述正在开发的系统想要实现的行为,而不必说明这些行为如何实现. 结构良好的用例只表示系统或者子系统的基本行为,而且既不过于笼统也不过于详细.
- 高级UI晋升之自定义View实战(八)
更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章自定义流式布局来进行介绍: 一般常见的流式布局由两种,一种是横向的个数固定 ...
- Python 如何debug
一.常见错误: 1.漏了末尾的冒号,如 if语句,循环语句,定义函数 2.缩进错误,该缩进的时候没有缩进 3.把英文符号写成中文符号,如: ' ' () , 4.字符串拼接,把字符串和数字拼接一起 ...
- window下eclipse搭建hadoop环境
1 生成插件jar 1.1 安装java,ant运行环境 1.2 下载hadoop-2.5.0.tar.gz并解压到指定目录 1.3 下载hadoop2x-eclipse-plugin-master. ...
- LeetCode Array Easy 88. Merge Sorted Array
Description Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted ar ...
- Lenovo E42-80安装Linux的注意事项
Lenovo E42-80安装Linux的注意事项 https://www.cnblogs.com/dylanchu/p/9750760.html 1. 用U盘做个liveCD While makin ...
- 在linux设置/etc/vimrc 将vim 中后缀.sh的文件 的前几行进行默认输入
输入vim test.sh 新建后缀sh的文件,效果如下: 具体/etc/vimrc配置为: if expand("%:e") == 'sh' call setline(1,&q ...
- rest_framework框架实现之(视图,路由,渲染器)
一视图 一 在前面我们使用视图时继承的时APIview from rest_framework.response import Response from rest_framework.paginat ...