专栏文章
题解:P14418 [JOISC 2014] 巴士走读 / Bus
P14418题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mincqba6
- 此快照首次捕获于
- 2025/12/02 00:16 3 个月前
- 此快照最后确认于
- 2025/12/02 00:16 3 个月前
排序 + 二分
题意
给定 个站点, 趟巴士: 表示 时刻从 出发, 时刻到达 的巴士。
JOI 君可以换乘公交车,只要前一辆到达当前站的时间 下一辆从该站的发车时间即可,换乘时间忽略。
给定 次询问,每次给定一个数 ,求 JOI 君最晚可以在什么时刻从公交站 1 出发,才能按时到达;若无法到达,输出 -1。
做法
我们要求在时间 前到达每个点的最晚出发时间 ,这里的 指从起点的最晚出发时间。
我们按到达时间 从小到大排序,这样枚举到的第 个巴士一定是当前到达 的最迟的巴士。
所以对于每一个点 ,我们维护 表示到达 的时间序列,因为排序所以有序; 表示在某一时间之前能到达站点 的最晚出发时间。
对于每一条巴士路径,我们在 站点二分第一个小于等于 时刻的最晚出发时间,如果它大于目前 站点的最晚出发时间那就加上,否则这劣于答案对答案无贡献。(这是贪心的思想,最晚出发时间肯定是要尽可能的晚,所以我们取最大值,并且这一步保证了答案维度的升序)。
特别的,站点为起点的最晚出发时间就是每条从起点出发的巴士的出发时间。
Code
CPP#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6 + 10;
template<typename TY>
inline void read(TY &s){
ll x = 0,f = 1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
s = x * f;
}
int n,m,q;
struct node{
int a,b,x,y;
}z[N];
bool cmp(node a,node b){
return a.y < b.y;
}
vector<int> ans[N],pos[N];
int main(){
read(n); read(m);
for(int i=1;i<=m;i++){
read(z[i].a); read(z[i].b); read(z[i].x); read(z[i].y);
}
sort(z+1,z+m+1,cmp);
for(int i=1;i<=n;i++) ans[i].push_back(-1),pos[i].push_back(0);
for(int i=1;i<=m;i++){
int a = z[i].a,b = z[i].b,x = z[i].x,y = z[i].y;
int maxn;
if(a == 1) maxn = x;
else maxn = ans[a][upper_bound(pos[a].begin(),pos[a].end(),x) - pos[a].begin() - 1];
if(maxn > ans[b][pos[b].size()-1]) ans[b].push_back(maxn),pos[b].push_back(y);
}
read(q);
int l = 0;
while(q--){
read(l);
cout << ans[n][upper_bound(pos[n].begin(),pos[n].end(),l) - pos[n].begin() - 1] << "\n";
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...