[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每秒会等概率选择一只鸽子并给他一粒玉米.一只鸽子饱了当且仅当它吃了的玉米粒数量\(≥ ...
随机推荐
- Paper | Residual Attention Network for Image Classification
目录 1. 相关工作 2. Residual Attention Network 2.1 Attention残差学习 2.2 自上而下和自下而上 2.3 正则化Attention 最近看了些关于att ...
- Pandas入门系列(一)-- Series
Series的创建 ##数据分析汇总学习 https://blog.csdn.net/weixin_39778570/article/details/81157884 # 使用列表创建 >> ...
- IT兄弟连 Java语法教程 数组 数组的声明
Java语言支持两种语法格式来定义数组: type[] arrayName; type arrayName[]; 对这两种语法格式而言,通常推荐使用第一种格式,因为第一种格式不仅具有更好的语义,而且具 ...
- vue实现页面跳转(简易版)
1.用点击函数 <button class="btntop" @click="gootherpage">跳转页面</button> 函数 ...
- Django之Django快速体验
Django快速体验 前语: 这一节内容是直接快速上手,后面的内容是对内容进行按步解释,如果不想看解析的,可以直接只看这一节的内容. 1.新建项目应用新建项目test1新建应用booktest 2.注 ...
- c# winfrom 更新控件时停止刷新,解决闪烁问题
static Dictionary<Control, bool> m_lstFreezeControl = new Dictionary<Control, bool>(); / ...
- wpf dual monitor
<Window x:Class="DualMonitors.Views.WinLeft" xmlns="http://schemas.microsoft.com/w ...
- 计时 答题 demo
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- 20个Python代码段,你需要立刻学会,好用到哭!
Python是一种非BS编程语言.设计简单和易读性是它广受欢迎的两大原因.正如Python的宗旨:美丽胜于丑陋,显式胜于隐式. 记住一些帮助提高编码设计的常用小诀窍是有用的.在必要时刻,这些小诀窍能够 ...
- sqlserver 问题来了,视图不会自动更新,如果是用*创建的
奇葩问题一个 create view时候用的select * 关联了几个表创建的. 后修改select * 的表,结果悲剧了. select * from 视图得到的结果绝对让你想哭.不报错,不提示 ...