[BZOJ4242]水壶(克鲁斯卡尔重构树,BFS) 题面 BZOJ然而是权限题. Description JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有P个,编号为1...P. JOI君只能进入建筑物与原野,而且每次只能走到相邻的区域中,且不能移动到市外. JOI君因为各种各样的事情,必须在各个建筑物之间往返.虽然建筑物中的冷气设备非常好,但原野上的日光十分强烈,因此在原野上每走过一个区域都需…
这次我们来搞一个很新奇的知识点:克鲁斯卡尔重构树.它也是一种图,是克鲁斯卡尔算法求最小生成树的升级版首先看下面一个问题:BZOJ3545 Peaks. 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走. 现在有Q组询问,每组询问询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰,如果无解输出-1.N<=1e5,M,Q<=5*1e5 上面这个题没有要求在线,因此我们可以离线构造…
传送门 据说离线做法是主席树上树+启发式合并(然而我并不会) 据说bzoj上有强制在线版本只能用克鲁斯卡尔重构树,那就好好讲一下好了 这里先感谢LadyLex大佬的博客->这里 克鲁斯卡尔重构树可以用来解决一类诸如“查询从某个点出发经过边权不超过val的边所能到达的节点”的问题 首先不难发现,上面这个问题肯定是在最小生成树上走最优,其他边都可以不用去管 那么我们就在建最小生成树的时候搞事情 克鲁斯卡尔重构树的思想就是在建最小生成树的时候不是直接连边,而是新建一个节点,并把这个节点的值设为边权,然…
题目描述 AAA国有nn n座城市,编号从 11 1到n nn,城市之间有 mmm 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 qqq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入输出格式 输入格式: 第一行有两个用一个空格隔开的整数n,m n,mn,m,表示 AAA 国有n nn 座城市和 mmm 条道路. 接下来 mmm行每行3 3 3个整数 x,y,zx, y, zx,y,z,每两个整数之间用一个空格隔开,表示从 xx x号城市…
[NOI2018]归程(克鲁斯卡尔重构树) 题面 洛谷 题解 我在现场竟然没有把这道傻逼题给切掉,身败名裂. 因为这题就是克鲁斯卡尔重构树的模板题啊 我就直接简单的说一下把 首先发现答案就是在只经过海拔大于\(p\)的边的情况下,所有点到\(1\)号点中最短路最小的那个点.所以预处理最短路径,构建克鲁斯卡尔重构树,直接倍增+线段树就好了. 还有一种基于离线做法的方法. 我们发现离线做法只需要按照所有询问排序, 然后利用并查集按照海拔高度从小往大合并(这个其实就是克鲁斯卡尔) 这样子就可以利用可持…
克鲁斯卡尔重构树 又叫并查集重构树 大概在NOI2018之前还是黑科技 现在?烂大街了 主要是针对图上的对边有限制的一类问题 比如每次询问一个点u不能经过边权大于w的边能走到的第k大点权是多少 也就是这个题peaks 首先肯定是一个最小生成树(如果不知道为什么还可以先做货车运输) 我们在并查集合并的时候稍作修改 每次不是fa[x]=y而是fa[x]=fa[y]=++tot 这样相当于新建了一个点连接两棵树,tot的点权根据题目需要确定 peaks这题点权就是所连边的边权 我们发现这样子构出来的树…
传送门 前置技能,克鲁斯卡尔重构树 我们按道路的高度建一个最大生成树,然后建好克鲁斯卡尔重构树 那么我们需要知道一颗子树内到1点距离最近是多少(除此之外到子树内任何一个点都不需要代价) 可以一开始直接跑一个dijkstra(关于SPFA,他死了) 然后一遍树形dp就可以了 //minamoto #include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include&…
克鲁斯卡尔重构树 发现没把板子放上来... 现在放一下 克鲁斯卡尔算法的正确性是利用反证法证明的. 简要地说, 就是如果不加入当前权值最小的边 \(e_1\), 那么之后加入的边和这条边会形成一个环. 去掉这个环上权值最大的边 \(e_2\) 并加入 \(e_1\), 答案不会更劣. struct te0{int f,t,v;}e0[msz]; bool operator<(te0 a,te0 b){return a.v>b.v;} int val[nsz*2],pd=0; int fa[ln…
Problem 在\(Bytemountains\)有\(n\)座山峰,每座山峰有他的高度\(h_i\) .有些山峰之间有双向道路相连,共\(M\)条路径,每条路径有一个困难值,这个值越大表示越难走,现在有\(Q\)组询问,每组询问询问从点\(v\)开始只经过困难值小于等于\(x\)的路径所能到达的山峰中第\(k\)高的山峰,如果无解输出\(-1\). kruskal重构树是用来解决一些诸如"查询从某个点开始 经过边权不超过\(val\)所能到达的节点"的问题 所以很显然 在最小生成树…
P5168 xtq玩魔塔 又是码农题- 利用克鲁斯卡尔重构树的性质 我们就可以得出 \(dep\) 值小的,肯定比 \(dep\) 大的值要优. 于是第二问就可以直接 LCA 求出来了- 至于第三问,dfs序一下,然后求子树-考虑莫队 修改直接带修莫队,没了. #include <bits/stdc++.h> using namespace std ; int min(int x , int y) { return x < y ? x : y ; } void swap(int &…