Luogu4768 NOI2018 归程 最短路、Kruskal重构树
题意:给出一个$N$个点、$M$条边的图,每条边有长度和海拔,$Q$组询问,每一次询问从$v$开始,经过海拔超过$p$的边所能到达的所有点中到点$1$的最短路的最小值,强制在线。$N \leq 2 \times 10^5 , M , Q \leq 4 \times 10^5$
关于$SPFA...$
与边的权值有关的连通块问题,经常可以考虑到$Kruskal$重构树。我们以海拔从大到小构建$Kruskal$重构树,那么对于每一次询问,可以到达的点就对应$Kruskal$重构树上的一棵子树。我们对于每一个点记录它的子树的叶子节点的最短路的最小值,每一次倍增找到询问对应的那一棵子树就能得到答案了。
#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;
inline int read(){
;
;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return f ? -a : a;
}
;
struct edge{
int start , end , hei;
}now[MAXN];
struct Edge{
int end , upEd , w;
}Ed[MAXN << ];
] , jump[MAXN << ][] , val[MAXN << ] , ans[MAXN << ] , ch[MAXN << ][] , cntNode , cntEd , N , M , Q;
priority_queue < pair < int , int > > q;
bool operator <(edge a , edge b){
return a.hei > b.hei;
}
int find(int a){
return fa[a] == a ? a : (fa[a] = find(fa[a]));
}
inline void addEd(int a , int b , int c){
Ed[++cntEd].end = b;
Ed[cntEd].upEd = head[a];
Ed[cntEd].w = c;
head[a] = cntEd;
}
void Dijk(){
memset(minDis , 0x7f , sizeof(minDis));
minDis[] = ;
q.push(make_pair( , ));
while(!q.empty()){
pair < int , int > t = q.top();
q.pop();
if(-t.first > minDis[t.second])
continue;
for(int i = head[t.second] ; i ; i = Ed[i].upEd)
if(minDis[Ed[i].end] > minDis[t.second] + Ed[i].w){
minDis[Ed[i].end] = minDis[t.second] + Ed[i].w;
q.push(make_pair(-minDis[Ed[i].end] , Ed[i].end));
}
}
}
void dfs(int node){
if(!node)
return;
; i <= && jump[node][i - ] ; ++i)
jump[node][i] = jump[jump[node][i - ]][i - ];
dfs(ch[node][]);
dfs(ch[node][]);
}
inline int jumpToAll(int x , int h){
; i >= ; --i)
if(val[jump[x][i]] > h)
x = jump[x][i];
return x;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("4768.in" , "r" , stdin);
//freopen("4768.out" , "w" , stdout);
#endif
for(int T = read() ; T ; --T){
memset(jump , , sizeof(jump));
memset(ch , , sizeof(ch));
memset(head , , sizeof(head));
cntEd = ;
N = read();
M = read();
; i <= M ; i++){
int a = read() , b = read() , c = read() , d = read();
now[i].start = a;
now[i].end = b;
now[i].hei = d;
addEd(a , b , c);
addEd(b , a , c);
}
Dijk();
; i <= N ; i++){
fa[i] = i;
ans[i] = minDis[i];
}
sort(now + , now + M + );
cntNode = N;
; i <= M ; ++i)
if(find(now[i].start) != find(now[i].end)){
int a = find(now[i].start) , b = find(now[i].end);
fa[a] = fa[b] = jump[a][] = jump[b][] = ++cntNode;
ch[cntNode][] = a;
ch[cntNode][] = b;
val[cntNode] = now[i].hei;
ans[cntNode] = min(ans[a] , ans[b]);
fa[cntNode] = cntNode;
}
dfs(cntNode);
, Q = read() , K = read() , S = read();
while(Q--){
int a = read() , b = read();
a = (0ll + a + K * lastans - ) % N + ;
b = (0ll + b + K * lastans) % (S + );
int t = jumpToAll(a , b);
printf("%d\n" , lastans = ans[t]);
}
}
;
}
Luogu4768 NOI2018 归程 最短路、Kruskal重构树的更多相关文章
- Luogu4768 NOI2018归程(最短路径+kruskal重构树)
按海拔从大到小合并建出kruskal重构树,这样就能知道开车能到达哪些点,对这些点到1的最短路取min即可.最难的部分在于多组数据的初始化和数组大小的设置. #include<iostream& ...
- 【NOI2018】归程 题解(kruskal重构树+最短路)
题目链接 题目大意:给定一张$n$个点$m$条边的无向图.每条边有长度和海拔.有$Q$次询问,每次给定起点$v$和当天水位线$p$,每次终点都是$1$.人可以选择坐车或走路,车只能在海拔大于水位线的路 ...
- LOJ #2718. 「NOI2018」归程(Dijkstra + Kruskal重构树 + 倍增)
题意 给你一个无向图,其中每条边有两个值 \(l, a\) 代表一条边的长度和海拔. 其中有 \(q\) 次询问(强制在线),每次询问给你两个参数 \(v, p\) ,表示在 \(v\) 出发,能开车 ...
- 洛谷P4768 [NOI2018]归程(克鲁斯卡尔重构树+最短路)
传送门 前置技能,克鲁斯卡尔重构树 我们按道路的高度建一个最大生成树,然后建好克鲁斯卡尔重构树 那么我们需要知道一颗子树内到1点距离最近是多少(除此之外到子树内任何一个点都不需要代价) 可以一开始直接 ...
- [NOI2018]归程 kruskal重构树
[NOI2018]归程 LG传送门 kruskal重构树模板题. 另一篇文章里有关于kruskal重构树更详细的介绍和更板子的题目. 题意懒得说了,这题的关键在于快速找出从查询的点出发能到达的点(即经 ...
- P4768 [NOI2018]归程(kruskal 重构树)
洛谷P4768 [NOI2018]归程 LOJ#2718.「NOI2018」归程 用到 kruskal 重构树,所以先说这是个啥 显然,这和 kruskal 算法有关系 (废话 这个重构树是一个有点权 ...
- [学习笔记]kruskal重构树 && 并查集重构树
Kruskal 重构树 [您有新的未分配科技点][BZOJ3545&BZOJ3551]克鲁斯卡尔重构树 kruskal是一个性质优秀的算法 加入的边是越来越劣的 科学家们借这个特点尝试搞一点事 ...
- BZOJ 4242: 水壶(Kruskal重构树 + Bfs)
题意 一块 \(h ∗ w\) 的区域,存在障碍.空地.\(n\) 个建筑,从一个建筑到另一个建筑的花费为:路径上最长的连续空地的长度. \(q\) 次询问:从建筑 \(s_i\) 到 \(t_i\) ...
- [luogu4768] [NOI2018] 归程 (Dijkstra+Kruskal重构树)
[luogu4768] [NOI2018] 归程 (Dijkstra+Kruskal重构树) 题面 题面较长,这里就不贴了 分析 看到不能经过有积水的边,即不能经过边权小于一定值的边,我们想到了kru ...
随机推荐
- Ant使用及项目实践
1.简介 Ant 是一个 Apache 基金会下的跨平台的基于 Java 语言开发的构件工具.这是一个基于开放的操作系统构建和部署的工具,该工具需要从命令行执行. 2.特点 Ant 是基于 Java ...
- sysbench对MySQL的压测,使用sysbench压测磁盘io
QPS - query per secondTPS - transaction per second 不是特别关注,每个业务场景中事务标准是不一样的 Ⅰ.sysbench测试框架 Ⅱ.常用测试脚本 [ ...
- Linux查看服务器配置常用
1. 内存: free:查看内存 total:总共内存 2. 处理器数量: cat /proc/cpuinfo | grep "processor" | wc -l 3.处理器 ...
- 使用LogPhoneUtil工具类在Android手机保存APP运行日志
最近公司的测试老是提出这样那样的bug,当然也怪自己代码写的烂,所以测试总是会把app搞崩溃,而他们那边崩溃的时候还没有日志打印,自己回来再重现有的时候还真不好复现出来,因此麻烦事就来了.为了方便查看 ...
- IntelliJ IDEA src下新建包, 没有层级结构
新建项目后再src先右键点击新建包 com.example , 然后想在com.example 包中包含其他包, 当点击src新建包后,出现如图的情况 解决: 继续在src上右键新建package ...
- ApplicationContext中Bean的生命周期
引言 Bean应用上下文中的生命周期和在BeanFactory中生命周期类似,不同的是,如果Bean实现了org.springframework.context.ApplicationContextA ...
- yii2 支付宝支付教程 [ 2.0 版本 ]
yii2 支付宝支付教程 [ 2.0 版本 ] 支付宝支付流程个人理解大致就这三步1.前台页面将支付信息数据通过立即支付按钮 ajax提交到订单处理层2.在订单处理层引用支付宝的接口 将支付数据写入 ...
- 【Java123】Java基础知识点
https://github.com/xbox1994/2018-Java-Interview 虽说不为面试做准备,仅仅就工作中遇到的很多Java问题,总是模棱两可的擦肩而过,真不是自己的风格. 还是 ...
- (转)yum提示Another app is currently holding the yum lock; waiting for it to exit...
文章转自 yum 下载东西突然卡主了,我直接ctrl+c退出,然后再次下载时候出现 Another app is currently holding the yum lock; waiting for ...
- mac版本idea使用(二)-如何安装PlantUML画时序图、类图
在跟踪spring源码的时候,看见网上的博客好多使用了idea自带的展示类继承关系图的功能,这个地方使用了idea的diagrams-show diagram,就可以显示类的继承图,很神奇的样子,记录 ...