BZOJ 4239 巴士走读
来源:互联网 发布:网络转换器联通转电信 编辑:程序博客网 时间:2024/04/27 22:34
最短路
和正解的做法不一样,不过都是
我的做法:也是最短路。把巴士看成点,并拆成入点和出点,边权为y-x(走它的意义是坐了这个巴士)。对于每一个原图的点u,把所有从这里出去的巴士按x排序,x小的前一辆i-1的入点向后一辆i的入点连边,边权x[i]-x[i-1](走它的意义是去考虑坐i号巴士并消耗等车时间)。把每一辆进入u的巴士的出点连向所有离开u的巴士中x恰好大于它的y的巴士的入点,边权为出去的那辆巴士的y-进入的那辆巴士的x(走它的意义是换车的等车时间)。跑最短路之后在s的出边二分即可。
正解(贴PO爷原文,戳我查看原文):将二元组<站点,时间>看做一个点,那么点数是O(m)的 ,每辆巴士连一条边,每个点向下一个时间连边,然后将所有边反向 ,枚举终点站的每一个时间,加入队列广搜,得到最晚多久到达1号站点可以在这个时间到达终点站,然后对于每个询问去数组中二分即可
好气啊,不知道怎么的刚开始偏大数据拍WA了,后来代码没改重新拍又拍不WA了,交上去居然A了。。。呵呵呵呵
#include<cstdio>#include<vector>#include<cstring>#include<algorithm>#include<queue>#define N 600005using namespace std;namespace runzhe2000{ int read() { int r = 0; char c = getchar(); for(; c < '0' || c > '9'; c = getchar()); for(; c >='0' && c <='9'; c = getchar()) r=r*10+c-'0'; return r; } const int INF = 1<<28; int n, m, last[N], ecnt, dis[N], T; bool vis[N]; vector<int> in[N], out[N]; struct edge{int next, to, val;}e[N<<1]; struct Bus{int a, b, x, y;}bus[N]; struct item{int x, dis;}; bool operator < (item a, item b) {return a.dis > b.dis;} bool cmp(int i1, int i2){return bus[i1].x < bus[i2].x;} void addedge(int a, int b, int c){e[++ecnt] = (edge){last[a], b, c}; last[a] = ecnt;} int pack(int i, int j){return i*2+j;} void dijkstra() { memset(dis, 63, sizeof(dis)); priority_queue<item> q; q.push((item){T, dis[T] = 0}); for(; !q.empty(); ) { int x = q.top().x; q.pop(); if(vis[x])continue; vis[x] = 1; for(int i = last[x]; i; i = e[i].next) { int y = e[i].to; if(dis[x] + e[i].val < dis[y]) q.push((item){y, dis[y] = dis[x] + e[i].val}); } } } void main() { n = read(), m = read(); for(int i = 1; i <= m; i++) { bus[i].a = read(), bus[i].b = read(), bus[i].x = read(), bus[i].y = read(); out[bus[i].a].push_back(i); in[bus[i].b].push_back(i); addedge(pack(i, 1), pack(i, 0), bus[i].y - bus[i].x); } for(int i = 1; i <= n; i++) out[i].push_back(0); bus[0].x = INF, bus[0].y = INF+INF; for(int i = 1; i < n; i++) { sort(out[i].begin(), out[i].end(), cmp); for(int j = 0; j < (int)in[i].size(); j++) { int u = in[i][j], l = 0, r = (int)out[i].size()-1; for(; l < r; ) { int mid = (l+r)>>1; if(bus[out[i][mid]].x >= bus[u].y) r = mid; else l = mid+1; } addedge(pack(out[i][l], 0), pack(u, 1), bus[out[i][l]].x - bus[u].y); } for(int j = 1; j < (int)out[i].size(); j++) addedge(pack(out[i][j], 0), pack(out[i][j-1], 0), bus[out[i][j]].x - bus[out[i][j-1]].x); } T = pack(m+1,0); for(int i = 0; i < (int)in[n].size(); i++) addedge(T, pack(in[n][i], 1), 0); dijkstra(); for(int i = 0; i < (int)out[1].size(); i++) dis[pack(out[1][i], 0)] += bus[out[1][i]].x; for(int Q =read(), t; Q--; ) { t = read(); int l = 0, r = out[1].size() - 1; for(; l < r; ) { int mid = (l+r+1)>>1; if(dis[pack(out[1][mid], 0)] <= t) l = mid; else r = mid - 1; } if(dis[pack(out[1][l], 0)] <= t) printf("%d\n",bus[out[1][l]].x); else puts("-1"); } }}int main(){ runzhe2000::main();}
0 0
- BZOJ 4239 巴士走读
- bzoj 4239: 巴士走读 类最短路
- [最短路] BZOJ 4239 巴士走读
- 卡常暴搜——bzoj4239: 巴士走读
- 图论——BZOJ4239 巴士走读
- 巴士快递
- 洛锡安巴士
- 巴士博弈
- 代码走读
- 巴士来了,巴士又走了
- 巴士卡里雅名言
- 情侣巴士嗌架
- 情侣巴士嗌架
- 首都机场巴士时刻
- 安卓巴士
- android巴士相关信息
- Android巴士转发
- hdu4764 Stone (巴士博弈)
- Git Submodule 命令
- ARP与RARP地址解析协议
- MySQL 5.7.13-winx64.zip安装笔记
- [初学Python]学习如何编写GUI界面(初级)
- 两个div并排显示--Dreamweaver一个模板的修改
- BZOJ 4239 巴士走读
- 动态链接库调用过程中不使用__declspec(dllimport)为何仍能调用?
- CCF201604-2 俄罗斯方块(100分)
- OpenCV实践(2)- 矩阵的掩码操作
- 2016杂记
- nyoj32_组合数
- 响应式和自适应区别
- Servlet-Filter和Listener
- 学习servlet的小曲折