[LOJ 2718][UOJ 393][BZOJ 5415][NOI 2018]归程
[LOJ 2718][UOJ 393][BZOJ 5415][NOI 2018]归程
题意
给定一张无向图, 每条边有一个距离和一个高度. 再给定 \(q\) 组可能在线的询问, 每组询问给定一个点 \(v\) 和一个高度 \(h\), 鸭子德可以先无需花费地在高度大于 \(h\) 的边上任意行动, 然后可以在任意点开始以花费等于距离的模式行动. 问最小的花费.
\(|V|\le 2\times 10^5,|E|\le 4\times 10^5,q\le 4\times 10^5,h\le 10^9\).
题解
显然带花费部分的行动是一个单源最短路. 那么我们只要求出无花费部分的行动可以到达的点中哪一个点距离 \(1\) 最近就可以了.
发现无花费部分是个类似瓶颈路的问题, 我们可以在 Kruskal 重构树上倍增求出能到达的点所组成的子树, 输出这个子树中的点到 \(1\) 的最短距离就可以了.
为啥我要写这个裸题的题解呢?
一个原因是存板子, 另一个原因是这个沙雕强制在线把我卡掉了 \(3\) 分qaq...具体情况
参考代码
#include <bits/stdc++.h>
const int MAXV=4e5+10;
const int MAXE=1e6+10;
struct Edge{
int from;
int to;
int dis;
int pos;
Edge* next;
bool friend operator>(const Edge& a,const Edge& b){
return a.pos>b.pos;
}
};
Edge E[MAXE];
Edge Ex[MAXE];
Edge* head[MAXV];
Edge* top=E;
int v;
int e;
int q;
int n;
int k;
int maxv;
int dis[MAXV];
int pos[MAXV];
int ufs[MAXV];
bool vis[MAXV];
int pprt[20][MAXV];
int* prt=pprt[0];
int ReadInt();
void Kruskal();
int FindRoot(int);
void Dijkstra(int);
void Insert(int,int,int,int);
int main(){
int T=ReadInt();
while(T--){
memset(pprt,0,sizeof(pprt));
memset(head,0,sizeof(head));
memset(vis,0,sizeof(vis));
top=E;
n=v=ReadInt();
e=ReadInt();
for(int i=0;i<e;i++){
int a=ReadInt(),b=ReadInt(),c=ReadInt(),d=ReadInt();
Ex[i]=Edge({a,b,c,d,NULL});
Insert(a,b,c,d);
Insert(b,a,c,d);
}
q=ReadInt(),k=ReadInt(),maxv=ReadInt();
Dijkstra(1);
Kruskal();
int lg=0;
for(int i=1;(1<<i)<=v;i++){
lg=i;
for(int j=1;j<=v;j++)
pprt[i][j]=pprt[i-1][pprt[i-1][j]];
}
int lastans=0;
while(q--){
int s=(0ll+ReadInt()+k*lastans-1)%n+1,h=(0ll+ReadInt()+k*lastans)%(maxv+1);
for(int i=lg;i>=0;i--){
if(pos[pprt[i][s]]>h)
s=pprt[i][s];
}
printf("%d\n",lastans=dis[s]);
}
}
return 0;
}
void Kruskal(){
std::sort(Ex,Ex+e,std::greater<Edge>());
for(int i=1;i<=v;i++)
ufs[i]=i;
int& cur=v;
for(int i=0;i<e;i++){
int a=FindRoot(Ex[i].from);
int b=FindRoot(Ex[i].to);
if(a!=b){
++cur;
pos[cur]=Ex[i].pos;
dis[cur]=std::min(dis[a],dis[b]);
prt[a]=cur;
prt[b]=cur;
ufs[cur]=cur;
ufs[a]=cur;
ufs[b]=cur;
}
}
}
void Dijkstra(int s){
std::priority_queue<std::pair<int,int>> q;
memset(dis,0x7F,sizeof(dis));
dis[s]=0;
q.emplace(0,s);
while(!q.empty()){
s=q.top().second;
q.pop();
if(vis[s])
continue;
vis[s]=true;
for(Edge* i=head[s];i!=NULL;i=i->next){
if(dis[i->to]>dis[s]+i->dis){
dis[i->to]=dis[s]+i->dis;
q.emplace(-dis[i->to],i->to);
}
}
}
}
inline void Insert(int from,int to,int dis,int pos){
top->from=from;
top->to=to;
top->dis=dis;
top->pos=pos;
top->next=head[from];
head[from]=top++;
}
int FindRoot(int x){
return ufs[x]==x?ufs[x]:ufs[x]=FindRoot(ufs[x]);
}
inline int ReadInt(){
int x=0;
register char ch=getchar();
while(!isdigit(ch))
ch=getchar();
while(isdigit(ch)){
x=x*10+ch-'0';
ch=getchar();
}
return x;
}
[LOJ 2718][UOJ 393][BZOJ 5415][NOI 2018]归程的更多相关文章
- [LOJ 2721][UOJ 396][BZOJ 5418][NOI 2018]屠龙勇士
[LOJ 2721][UOJ 396][BZOJ 5418][NOI 2018]屠龙勇士 题意 题面好啰嗦啊直接粘LOJ题面好了 小 D 最近在网上发现了一款小游戏.游戏的规则如下: 游戏的目标是按照 ...
- [LOJ 2134][UOJ 132][BZOJ 4200][NOI 2015]小园丁与老司机
[LOJ 2134][UOJ 132][BZOJ 4200][NOI 2015]小园丁与老司机 题意 给定平面上的 \(n\) 个整点 \((x_i,y_i)\), 一共有两个问题. 第一个问题是从原 ...
- [LOJ 2133][UOJ 131][BZOJ 4199][NOI 2015]品酒大会
[LOJ 2133][UOJ 131][BZOJ 4199][NOI 2015]品酒大会 题意 给定一个长度为 \(n\) 的字符串 \(s\), 对于所有 \(r\in[1,n]\) 求出 \(s\ ...
- [LOJ 2083][UOJ 219][BZOJ 4650][NOI 2016]优秀的拆分
[LOJ 2083][UOJ 219][BZOJ 4650][NOI 2016]优秀的拆分 题意 给定一个字符串 \(S\), 求有多少种将 \(S\) 的子串拆分为形如 AABB 的拆分方案 \(| ...
- [NOI 2018] 归程
Description 传送门 Solution 65分做法 先求出每个点到\(1\)号点的最短路,记为\(d[i]\).然后按照海拔从大到小依次加边,并查集维护每个连通块中\(d[i]\)的最小值, ...
- 解题:NOI 2018 归程
题面 清新友好的题目 跑一个最短路,然后对海拔建Kruskal重构树,从最后接上去的边(最低的一个)开始DFS一下处理子树里路程的最小值. 询问是每次在重构树上倍增找到深度最浅的海拔高于当天水位线的节 ...
- NOI 2018 归程 (Kruskal重构树)
题目大意:太长了,略 Kruskal重构树,很神奇的一个算法吧 如果两个并查集被某种条件合并,那么这个条件作为一个新的节点连接两个并查集 那么在接下来的提问中,如果某个点合法,它的所有子节点也都合法, ...
- [LOJ 2720][BZOJ 5417][UOJ 395][NOI 2018]你的名字
[LOJ 2720][BZOJ 5417][UOJ 395][NOI 2018]你的名字 题意 给定一个大串 \(S\) 以及 \(q\) 次询问, 每次询问给定一个串 \(T\) 和区间 \([l, ...
- UOJ #449. 【集训队作业2018】喂鸽子
UOJ #449. [集训队作业2018]喂鸽子 小Z是养鸽子的人.一天,小Z给鸽子们喂玉米吃.一共有n只鸽子,小Z每秒会等概率选择一只鸽子并给他一粒玉米.一只鸽子饱了当且仅当它吃了的玉米粒数量\(≥ ...
随机推荐
- Python程序中的进程操作-进程间数据共享(multiprocess.Manager)
目录 一.进程之间的数据共享 1.1 Manager模块介绍 1.2 Manager例子 一.进程之间的数据共享 展望未来,基于消息传递的并发编程是大势所趋 即便是使用线程,推荐做法也是将程序设计为大 ...
- python做中学(六)os.getcwd() 的用法
概述 os.getcwd() 方法用于返回当前工作目录. 语法 getcwd()方法语法格式如下: os.getcwd() 参数 无 返回值 返回当前进程的工作目录. 实例 以下实例演示了 getcw ...
- Jmeter之用于json格式的响应断言
当响应结果是json格式时,用JSON Assertion更方便判断. 1 在请求上右键添加json断言 2 编辑json Assertion 判断方式: 如果响应结果不是json格式的,fail ...
- 正则表达式中的.*?和python中re.S参数的详解
本章的内容主要是为讲解在正则表达式中常用的.*?和re.S! 在正则表达式中有贪婪匹配和最小匹配:如下为贪婪匹配(.*) import re match = re.search(r'PY.*', 'P ...
- GPU跑tf-faster-rcnn demo以及训练自己的数据
https://blog.csdn.net/qq_39123369/article/details/85245512
- Java设计模式:Factory Method(工厂方法)模式
概念定义 工厂方法(Factory Method)模式,又称多态工厂(Polymorphic Factory)模式或虚拟构造器(Virtual Constructor)模式.工厂方法模式通过定义工厂抽 ...
- Vue实现简单的列表金额计算效果(简易购物车)
效果图: 使用技术:v-for v-bind v-on实现简单的列表选中绑定操作 代码: <!DOCTYPE html> <html> <head> <met ...
- 2019-9-23-win10-uwp-睡眠唤醒
原文:2019-9-23-win10-uwp-睡眠唤醒 title author date CreateTime categories win10 uwp 睡眠唤醒 lindexi 2019-9-23 ...
- Python爬取知乎单个问题下的回答
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 努力学习的渣渣哦 PS:如有需要Python学习资料的小伙伴可以加 ...
- 版本管理·玩转git(日志查看与版本切换)
如果你想更清晰地学习git,你必须要了解3个重要区域. 工作区:即开发者的工作目录 暂存区:修改已被记录,但尚未录入版本库的区域 版本库:存储变化日志及版本信息 当你在工作区进行开发工作时,git会记 ...