【luoguP4768】【NOI2018】归程
description
本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定。 魔力之都可以抽象成一个 nn 个节点、mm 条边的无向连通图(节点的编号从 11 至 nn)。我们依次用 l,al,a 描述一条边的长度、海拔。 作为季风气候的代表城市,魔力之都时常有雨水相伴,因此道路积水总是不可避免 的。由于整个城市的排水系统连通,因此有积水的边一定是海拔相对最低的一些边。我们用水位线来描述降雨的程度,它的意义是:所有海拔不超过水位线的边都是有积水的。
Yazid 是一名来自魔力之都的OIer,刚参加完ION2018 的他将踏上归程,回到他 温暖的家。 Yazid 的家恰好在魔力之都的 11 号节点。对于接下来 QQ 天,每一天Yazid 都会告诉你他的出发点 vv ,以及当天的水位线pp。 每一天,Yazid 在出发点都拥有一辆车。这辆车由于一些故障不能经过有积水的边。 Yazid 可以在任意节点下车,这样接下来他就可以步行经过有积水的边。但车会被留在他下车的节点并不会再被使用。 需要特殊说明的是,第二天车会被重置,这意味着:
车会在新的出发点被准备好。
Yazid 不能利用之前在某处停放的车。
Yazid 非常讨厌在雨天步行,因此他希望在完成回家这一目标的同时,最小化他步行经过的边的总长度。请你帮助 Yazid 进行计算。 本题的部分测试点将强制在线,具体细节请见【输入格式】和【子任务】。
kruskal构造树
首先得先学这个东东;可以按照\(kruskal\)建\(MST\)的思想来建出一个无向图的\(kruskal\)构造树
具体就是按边长度排序后,若边\((x,y)\)中\(x,y\)不连通,建一个新点,新点点权设为边权,把两个集合连到新点上
若边升序排序,则对于\((u,v)\)两点,\(LCA(u,v)\)点权即为原图中\(u\)到\(v\)所有路径中最大边权的最小值
降序排序则是最小边权的最大值;还有一些有意思的性质,比如构造树是二叉树、大(小)根堆
analysis
对于点\(x\)需要知道\(x\)可以走到的点都有哪些,若建出海拔的\(kruskal\)构造树,深度越浅点权越小,就是海拔越小
找到构造树中深度最浅且满足海拔恰好\(>p\)的某个点,那该点的子树中所有点都可以开车互相可达
找这个点可以倍增,由于这些点都可达且剩下没有点可以不下车到达,答案即为该点的子树中到\(1\)的距离的最小值
求\(1\)到每个点的距离用\(dij\)就好了
code
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<queue>
#define MAXN 400005
#define MAXM 400005
#define reg register int
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define rep(i,a) for (reg i=las[a];i;i=nex[i])
using namespace std;
int las[MAXM*2],nex[MAXM*2],tov[MAXM*2],len[MAXM*2];
int fa[MAXN],dis[MAXN],val[MAXN],mn[MAXN];
int n,m,q,k,s,T,tot,cnt,lastans;
int anc[MAXN][20];
bool bz[MAXN];
struct edge
{
int x,y,len,height;
}f[MAXM];
struct node
{
int x,y;
bool operator<(const node &a)const{return a.y<y;}
};
priority_queue<node>que;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline int max(int x,int y){return x>y?x:y;}
inline int min(int x,int y){return x<y?x:y;}
inline bool cmp(edge a,edge b){return a.height>b.height;}
inline int getfa(int x){return fa[x]==x?x:fa[x]=getfa(fa[x]);}
inline void link(int x,int y){nex[++tot]=las[x],las[x]=tot,tov[tot]=y;}
inline void linkk(int x,int y,int z){nex[++tot]=las[x],las[x]=tot,tov[tot]=y,len[tot]=z;}
inline void dfs(int x)
{
mn[x]=dis[x];
rep(i,x)anc[tov[i]][0]=x,dfs(tov[i]),mn[x]=min(mn[x],mn[tov[i]]);
}
inline void build()
{
fo(i,1,n)fa[i]=i;sort(f+1,f+m+1,cmp);
fo(i,1,m)
{
int fx=getfa(f[i].x),fy=getfa(f[i].y);
if (fx!=fy)
{
val[++cnt]=f[i].height;
fa[cnt]=fa[fx]=fa[fy]=cnt;
link(cnt,fx),link(cnt,fy);
}
}
dfs(cnt);
}
inline void dijkstra()
{
memset(bz,1,sizeof(bz));
memset(dis,100,sizeof(dis));
que.push((node){1,dis[1]=0});
while (!que.empty())
{
node now=que.top();que.pop();
if (!bz[now.x])continue;bz[now.x]=0;
rep(i,now.x)if (dis[now.x]+len[i]<dis[tov[i]])
{
dis[tov[i]]=dis[now.x]+len[i];
if (bz[tov[i]])que.push((node){tov[i],dis[tov[i]]});
}
}
}
int main()
{
//freopen("P4768.in","r",stdin);
T=read();
while (T--)
{
memset(las,0,sizeof(las)),memset(nex,0,sizeof(nex)),
memset(nex,0,sizeof(nex)),memset(len,0,sizeof(len)),tot=lastans=0;
n=cnt=read(),m=read();
fo(i,1,m)f[i].x=read(),f[i].y=read(),f[i].len=read(),f[i].height=read(),
linkk(f[i].x,f[i].y,f[i].len),linkk(f[i].y,f[i].x,f[i].len);
dijkstra();
memset(las,0,sizeof(las)),memset(nex,0,sizeof(nex)),
memset(nex,0,sizeof(nex)),memset(len,0,sizeof(len)),tot=0;
memset(mn,100,sizeof(mn));
build(),q=read(),k=read(),s=read();
int log=(int)log2(cnt);
fo(j,1,log)fo(i,1,cnt)anc[i][j]=anc[anc[i][j-1]][j-1];
fo(i,1,q)
{
int v=(read()+k*lastans-1)%n+1,p=(read()+k*lastans)%(s+1);
fd(j,19,0)if (anc[v][j] && val[anc[v][j]]>p)v=anc[v][j];
printf("%d\n",lastans=mn[v]);
}
}
return 0;
}
【luoguP4768】【NOI2018】归程的更多相关文章
- luoguP4768 [NOI2018]归程
传送门 kruskal重构树: kruskal合并两个联通块时合并的边一定是联通块中权值最大的边,小于等于这条边的边所能联通的所有点在这个联通块中. 在合并两个联通块的时候新建一个点作为两个联通块代表 ...
- [NOI2018]归程 kruskal重构树
[NOI2018]归程 LG传送门 kruskal重构树模板题. 另一篇文章里有关于kruskal重构树更详细的介绍和更板子的题目. 题意懒得说了,这题的关键在于快速找出从查询的点出发能到达的点(即经 ...
- [洛谷P4768] [NOI2018]归程 (kruskal重构树模板讲解)
洛谷题目链接:[NOI2018]归程 因为题面复制过来有点炸格式,所以要看题目就点一下链接吧\(qwq\) 题意: 在一张无向图上,每一条边都有一个长度和海拔高度,小\(Y\)的家在\(1\)节点,并 ...
- NOI2018 D1T1 [NOI2018]归程 解题报告
P4768 [NOI2018]归程 题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 \(n\) 个节点.\(m\) 条边的无向连通图(节点的编号从 \ ...
- BZOJ_5415_[Noi2018]归程_kruscal重构树+倍增+最短路
BZOJ_5415_[Noi2018]归程_kruscal重构树+倍增 Description www.lydsy.com/JudgeOnline/upload/noi2018day1.pdf 好久不 ...
- 题解 NOI2018 归程
题解 NOI2018 归程 题意 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 n 个节点.m 条边的无向连通图(节点的编号从 1 至 n).我们依次用 l, ...
- [NOI2018]归程(kruscal重构树)
[NOI2018]归程 题面太长辣,戳这里 模拟赛上写了一个spfa (关于spfa,它已经死了),然后一个st表水完暴力跑路.考后说是Kruscal重构树或者可持久化并查集???这都是些什么东西.不 ...
- [luogu4768] [NOI2018] 归程 (Dijkstra+Kruskal重构树)
[luogu4768] [NOI2018] 归程 (Dijkstra+Kruskal重构树) 题面 题面较长,这里就不贴了 分析 看到不能经过有积水的边,即不能经过边权小于一定值的边,我们想到了kru ...
- Luogu P4768 [NOI2018]归程(Dijkstra+Kruskal重构树)
P4768 [NOI2018]归程 题面 题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 \(n\) 个节点. \(m\) 条边的无向连通图(节点的编 ...
- P4768 [NOI2018]归程(kruskal 重构树)
洛谷P4768 [NOI2018]归程 LOJ#2718.「NOI2018」归程 用到 kruskal 重构树,所以先说这是个啥 显然,这和 kruskal 算法有关系 (废话 这个重构树是一个有点权 ...
随机推荐
- python2和python3中TestSuite().addTest的区别
Python2中unittest.TestSuite().addTest()的参数是这样的:unittest.TestSuite().addTest(TestFun("test_nam&qu ...
- 记一次pycharm和vscode因网络问题插件下载失败的问题
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connec ...
- Database基础(七):部署集群基础环境、MySQL-MMM架构部署、MySQL-MMM架构使用
一.部署集群基础环境 目标: 本案例要求为MySQL集群准备基础环境,完成以下任务操作: 数据库授权 部署MySQL双主多从结构 配置本机hosts解析记录 方案: 使用4台RHEL 6虚拟机,如下图 ...
- 腾讯云ubuntu16.04安装MySql5.7未提示密码设置且无法登陆解决
一.安装 sudo apt-get update sudo apt install mysql-server 二.修改密码 1.由于安装过程中未提示要设置密码,且使用sudo mysql_secure ...
- ylbtech-公司-滴滴出行:滴滴出行
ylbtech-公司-滴滴出行:滴滴出行 滴滴出行是涵盖出租车. 专车. 滴滴快车. 顺风车. 代驾及 大巴等多项业务在内的一站式出行平台,2015年9月9日由“滴滴打车”更名而来. 2月1日起, ...
- Struts1.3——文件上传和下载
1.Struts文件上传 在Web开发中,会经常涉及到文件的上传和下载,比如在注册账户的时候,我们需要上传自己的头像等. 我们可以利用Struts很方便地实现文件的上传. 1.1 开发步骤 现在,假设 ...
- upc组队赛3 Iranian ChamPions Cup
Iranian ChamPions Cup 题目描述 The Iranian ChamPions Cup (ICPC), the most prestigious football league in ...
- java多线程学习笔记(三)
java多线程下的对象及变量的并发访问 上一节讲到,并发访问的时候,因为是多线程,变量如果不加锁的话,会出现“脏读”的现象,这个时候需要“临界区”的出现去解决多线程的安全的并发访问.(这个“脏读”的现 ...
- Linux(二)—— Linux配置及指令
目录 Linux配置及指令 一.linux中常用软件的安装 二.主机名和网络 1.修改主机名 2.设置网络 三.关闭防火墙 1.检查防火墙是否开启 2.清除策略 3.永久关闭第一个防火墙 4.关闭第二 ...
- Tika教程
Apache Tika 是什么? Apache Tika用于文件类型检测和从各种格式的文件内容提取的库. 在内部,Tika使用现有的各种文件解析器和文档类型的检测技术来检测和提取数据. 使用Tika, ...