Problem

在\(Bytemountains\)有\(n\)座山峰,每座山峰有他的高度\(h_i\) 。有些山峰之间有双向道路相连,共\(M\)条路径,每条路径有一个困难值,这个值越大表示越难走,现在有\(Q\)组询问,每组询问询问从点\(v\)开始只经过困难值小于等于\(x\)的路径所能到达的山峰中第\(k\)高的山峰,如果无解输出\(-1\)。

kruskal重构树是用来解决一些诸如“查询从某个点开始 经过边权不超过\(val\)所能到达的节点”的问题

所以很显然 在最小生成树上是最优的。。其他多余的边可以不需要考虑。。

那我们在跑kruskal的时候重新建边。。

克鲁斯卡尔重构树的思想就是在建最小生成树的时候不是直接连边 而是新建一个节点 并把这个节点的值设为边权 然后令两个连通块的代表点分别作为它的左右儿子 然后令这个新节点成为整个连通块的代表点

即如果\(u\) \(v\)不连通

把\(u\) \(v\)两点连到新建节点上。顺便连边。然后就变成了一棵树。

而这棵树满足一个性质 十分重要 树满足一个最优性…至于图…不放了…自己手动模拟一下就知道了啊…把边权化成点权然后求个[LCA]通常是这个套路吧…

但是这题貌似不太一样…要按上一个主席树…

sort(q + 1 , q + m + 1 , cmp) ;
for( int i = 1 ; i <= n ; i ++ ) fa[i] = i ;
tot = n ;
for( int i = 1 ; i <= m ; i ++ ) {
int u = find(q[i].u) , v = find(q[i].v) ;
if(u == v) continue ;
val[++ tot] = q[i].w ; fa[tot] = fa[u] = fa[v] = tot ;
add(tot , u) ; add(tot , v) ;
}

所以把新建的树变成dfs序放到主席树上解决就可以了(在线)。。

#include<bits/stdc++.h>
using namespace std ;
const int N = 2e5 + 5 ;
const int M = 5e5 + 5 ;
const int inf = INT_MAX ;
struct node { int v , nxt ; } e[N << 1] ;
struct Node { int u , v , w ; } q[M] , t[N << 1] ;
int n , m , Q ;
int rt[N] , h[N] ;
int ls[N << 5] , rs[N << 5] , sum[N << 5] ;
int val[N] ;
int head[N] , cnt = 0 ;
inline void add(int u , int v) { e[++ cnt] = { v , head[u]} ; head[u] = cnt ; }
inline bool cmp(Node x , Node y) { return x.w < y.w ; }
int fa[N] ; int tot ;
inline int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]) ; }
inline void kruskal() {
sort(q + 1 , q + m + 1 , cmp) ;
for( int i = 1 ; i <= n ; i ++ ) fa[i] = i ;
tot = n ;
for( int i = 1 ; i <= m ; i ++ ) {
int u = find(q[i].u) , v = find(q[i].v) ;
if(u == v) continue ;
val[++ tot] = q[i].w ; fa[tot] = fa[u] = fa[v] = tot ;
add(tot , u) ; add(tot , v) ;
}
}
int f[N][22], L[N] , R[N] ;
int b[N] , pop = 0 ;
inline void dfs(int u , int fa) {
f[u][0] = fa ;
for( int i = 1 ; i <= 19 ; i ++ ) f[u][i] = f[f[u][i - 1]][i - 1] ;
L[u] = pop ;
if(! head[u]) { b[++ pop] = u ; R[u] = pop ; return ; }
for( int i = head[u] ; i ; i = e[i].nxt) {
int v = e[i].v ; dfs(v , u) ;
} R[u] = pop ;
}
inline void build(int l , int r , int & o) {
o = ++ cnt ;
if(l == r) return ;
int mid = l + r >> 1 ;
build(l , mid , ls[o]) ; build(mid + 1 , r , rs[o]) ;
}
inline void upd(int l , int r , int pre , int & o , int x) {
o = ++ cnt ;
ls[o] = ls[pre] ; rs[o] = rs[pre] ; sum[o] = sum[pre] ;
if(l == r) { sum[o] ++ ; return ; }
int mid = l + r >> 1 ;
if(x <= mid) upd(l , mid , ls[pre] , ls[o] , x) ;
else upd(mid + 1 , r , rs[pre] , rs[o] , x) ;
sum[o] = sum[ls[o]] + sum[rs[o]] ;
}
inline int find_fa(int x , int k) {
for(register int i = 19 ; ~ i ; i --)
if(val[f[x][i]] <= k) x = f[x][i] ;
return x ;
}
inline int query(int a , int b , int l , int r , int k) {
if(l == r)
if(k == sum[b] - sum[a]) return l ;
else return 0 ;
int x = sum[rs[b]] - sum[rs[a]] , mid = l + r >> 1 ;
if(x >= k) return query(rs[a] , rs[b] , mid + 1 , r , k) ;
else return query(ls[a] , ls[b] , l , mid , k - x) ;
}
signed main() {
ios :: sync_with_stdio(false) ;
cin.tie(nullptr) ;
cout.tie(nullptr) ;
cin >> n >> m >> Q ;
val[0] = inf ;
for( int i = 1 ; i <= n ; i ++ ) cin >> h[i] ;
for( int i = 1 ; i <= n ; i ++ ) t[i].u = i , t[i].w = h[i] ;
sort(t + 1 , t + n + 1 , cmp) ;
for( int i = 1 ; i <= n ; i ++ ) h[t[i].u] = i ;
for( int i = 1 ; i <= m ; i ++ ) { cin >> q[i].u >> q[i].v >> q[i].w ; }
kruskal() ;
dfs(tot , tot) ; cnt = 0 ;
build(1 , n , rt[0]) ;
for( int i = 1 ; i <= pop ; i ++)
upd(1 , n , rt[i - 1] , rt[i] , h[b[i]]) ;
t[0].w = -1 ;
for( int i = 1 ; i <= Q ; i ++) {
int v , x , k ; cin >> v >> x >> k ;
int fa = find_fa(v , x) ;
int ans = query(rt[L[fa]] , rt[R[fa]] , 1 , n , k) ;
cout << t[ans].w << '\n' ;
}
return 0 ;
}

P4197 Peaks [克鲁斯卡尔重构树 + 主席树][克鲁斯卡尔重构树学习笔记]的更多相关文章

  1. 2018.09.30 bzoj3551:Peaks加强版(dfs序+主席树+倍增+kruskal重构树)

    传送门 一道考察比较全面的题. 这道题又用到了熟悉的kruskal+倍增来查找询问区间的方法. 查到询问的子树之后就可以用dfs序+主席树统计答案了. 代码: #include<bits/std ...

  2. luoguP4197:Peaks(Kruskal重构树+主席树)或者(点分树+离线)

    题意:有N座山,M条道路.山有山高,路有困难值(即点权和边权).现在Q次询问,每次给出(v,p),让求从v出发,只能结果边权<=p的边,问能够到达的山中,第K高的高度(从大到小排序). 思路:显 ...

  3. bzoj3545: [ONTAK2010]Peaks 重构树 主席树

    题目链接 bzoj3545: [ONTAK2010]Peaks 题解 套路重构树上主席树 代码 #include<cstdio> #include<algorithm> #de ...

  4. BZOJ_3545_[ONTAK2010]Peaks_主席树+倍增+kruscal重构树+dfs序

    BZOJ_3545_[ONTAK2010]Peaks_主席树+倍增+kruscal重构树 Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道 ...

  5. 洛谷P4197 Peaks&&克鲁斯卡尔重构树学习笔记(克鲁斯卡尔重构树+主席树)

    传送门 据说离线做法是主席树上树+启发式合并(然而我并不会) 据说bzoj上有强制在线版本只能用克鲁斯卡尔重构树,那就好好讲一下好了 这里先感谢LadyLex大佬的博客->这里 克鲁斯卡尔重构树 ...

  6. [luogu P4197] Peaks 解题报告(在线:kruskal重构树+主席树 离线:主席树+线段树合并)

    题目链接: https://www.luogu.org/problemnew/show/P4197 题目: 在Bytemountains有N座山峰,每座山峰有他的高度$h_i$.有些山峰之间有双向道路 ...

  7. 洛谷P4197 Peaks(Kruskal重构树 主席树)

    题意 题目链接 往后中文题就不翻译了qwq Sol 又是码农题..出题人这是强行把Kruskal重构树和主席树拼一块了啊.. 首先由于给出的限制条件是<=x,因此我们在最小生成树上走一定是最优的 ...

  8. 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1202  Solved: 321[Submit][Sta ...

  9. [BZOJ3551][ONTAK2010]Peaks(加强版)(Kruskal重构树,主席树)

    3551: [ONTAK2010]Peaks加强版 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2438  Solved: 763[Submit][ ...

随机推荐

  1. 请注意安全!你的mongodb已经被黑了!互联网安全生产大过天!

    你所不知道的入侵,你的服务器安全吗?你的数据库安全吗? 讲真,也许是我以前一直从事内网应用开发吧,我从来没有想过在互联网上,有那么多扫描器. 10月份的时候,受人委托我做了一个简单的抢单插件,里面有用 ...

  2. Hibernate(六)

    ================================缓存============================定义:介于应用程序和永久性数据存储源之间,可以复制数据存储源中的数据. 工作 ...

  3. 五大常见算法策略之——动态规划策略(Dynamic Programming)

    Dynamic Programming   Dynamic Programming是五大常用算法策略之一,简称DP,译作中文是"动态规划",可就是这个听起来高大上的翻译坑苦了无数人 ...

  4. ERP入门到精通

    大家好,最近有空就跟大家分享开发ERP经验,希望对大家有所帮助. 少说废话,直接进入主题吧. ERP定义:企业资源计划 企业资源:物资资源,人力资料,财务资源,信息资源 包含内容:制造,会计,财务,销 ...

  5. Visual Studio 2015 配置 Python 环境

    Visual Studio 2015可以在安装时选择安装Python环境,首次使用VS2015执行python时需要配置环境变量: 配置VS2015的环境前需要先下载Python并安装: https: ...

  6. Python单引号、双引号、三个双引号的区别

    单引号与双引号是作用是一样的,都是字符串定界符. 如果字符串里面包含的与边界一样的符号,需要转义符来将该符号转成普通字符,不然编译器会将字符串中的那个单引号或双引号当成字符串的边界. 例如: ‘I d ...

  7. PYTHON 学习笔记2 流程控制工具以及函数定义、匿名函数

    前言 在上一节的学习中.已经介绍了几种基本类型.包括字符串的定义,以及字符串中索引.切片.字符串拼接的使用方法.以及基本的整形数据运算.一些之前都没有了解过的运算符.比如 ** 乘方 //整数除法等. ...

  8. gcc, ld

    GCC gcc除了具备基本的c文件编译功能外,还把其它工具的功能也集成了进来,比如as的汇编功能,ld的链接功能. 因此,gcc也可以通过-Wa, option,将option传给汇编器as:也可以通 ...

  9. U盘模式无法引导进入pe系统

        有些笔记本.一体机 特别是win8.win10系统维护时需要 通过u盘进入pe系统,就是进不去,需要到bios中更改一下设置.            1.首先我们将已经使用u启动u盘启动盘制作 ...

  10. HSRP 详解

    简介 HSRP(Hot Standby Router Protocol 热备份路由器协议)是Cisco的专有协议.HSRP把多台路由器组成一个“热备份组”,形成一个虚拟路由器.这个组内只有一个路由器是 ...