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 ...
随机推荐
- video 铺满父元素(object-fit: fill;)
遇到这个属性,是在给video 嵌入一个div时,导致video播放器上下有灰色.在控制台查看video默认样式的时候看到了这个属性. 播放器上下的灰色,不是我们想要的样式,如果能完全覆盖就更好了. ...
- Chrome调试本地文件无法使用window.opener对象进行窗口间值传递
今天在百度BAE上建了个应用,svn上传后发现页面间互调有些问题,几经查询发现: (1)IE下正常的window.opener.object1.object2页面间对象访问方法在Chrome下不能使用 ...
- OkHttp3源码详解(一) Request类
每一次网络请求都是一个Request,Request是对url,method,header,body的封装,也是对Http协议中请求行,请求头,实体内容的封装 public final class R ...
- springcloud 入门 8 (config配置中心)
Spring Cloud Config: 配置中心为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件,它就是Spring Cloud Config. 在分布式系统中,由于服务数量巨多, ...
- 洗礼灵魂,修炼python(20)--自定义函数(1)—基础概念
作为开发,那么我们前面学的那些知识其实够了,但是不够精简,也不好维护,比如需要打印斐波那契数列: 而当我们需要再次打印斐波那契数列,又要把这段代码加上,是不是很烦,有没有方法可以解决,当然可以,那就是 ...
- 解决SQL Server本地Windows身份无法登录
CREATE LOGIN [计算机名\Windows帐户名] FROM WINDOWS
- datatable 列名重新排序
1. DataTable.Columns["MONEY"].SetOrdinal[4]; 2.dt = dt.DefaultView.ToTable(false, listarr. ...
- Windows:添加、删除和修改静态路由
添加一条路由 route add 删除一条路由 route add -p #作用同上,只是这是一条永久路由,不会因为重启机器而丢失. 注意:如果有两条路由记录有着相同的“目的网络号”,则会将两条记录 ...
- mysql状态分析之show global status(转)
mysql> show global status;可以列出MySQL服务器运行各种状态值,我个人较喜欢的用法是show status like '查询值%';一.慢查询mysql> sh ...
- 用JQuery操作元素的style属性
可以直接利用css()方法获取元素的样式属性,JQuery代码如下: 1 $("p").css("color"); //获取p元素的样式颜色 无论color属 ...