P4678 [BalticOI 2005] Bus Trip 题解(RE:题解再改造!!)
贴码
#include<bits/stdc++.h>
#define MAXN 500010
using namespace std;
//ifstream is("trip.in",ios::in);
//ofstream os("trip.out",ios::out);
//#define cin is
//#define cout os
int n,m,p,t,tote,dist[MAXN],ans[MAXN];
struct Bus {
int x,t,idx,dist;
}b[MAXN];
void build(int x,int t,int idx,int dist){
b[++tote]={x,t,idx,dist};
}
bool cmp(const Bus &x,const Bus &y){
return x.t==y.t?x.dist>y.dist:x.t<y.t;
}
int main(){
ios::sync_with_stdio(0);
cin>>n>>m>>p>>t;
for(int i=1,s,t,a,b,c,d;i<=m;i++){
cin>>s>>t>>a>>b>>c>>d;
build(s,a,i,0);
build(t,d,i,c-b);
}
build(n+1,t,0,-0x3f3f3f3f);
sort(b+1,b+tote+1,cmp);
memset(dist,250,sizeof(dist));
dist[1]=0;
for(int i=1;i<=tote;i++){
if(b[i].x==n+1) break;
if(!b[i].dist) ans[b[i].idx]=dist[b[i].x];
else dist[b[i].x]=max(dist[b[i].x],ans[b[i].idx]+b[i].dist);
}
(dist[p]<0)?cout<<"-1":cout<<t-dist[p];
return 0;
}
正文
本题关键在于把最坏等待时间转化成中间乘坐公交的最长时间。
即每次乘车都看成a_i上车b_i开车,c_i抵达d_i下车,等待时间拉满。
此时车上时间为c_i-b_i
build建点时存储的几个变量:出发点/到达点,出发/到达最终时间,第idx号公交车,b_i.dist为这班车到达此点的乘车耗时。
把边排序的时候使用的排序规则为:
-
最终时间相同时,乘车时间越长排越前面
-
最终时间不同时,最终时间更长排越后面
dist需赋一个负的极小值(赋250或0xcf均可,赋250是因为250的二进制是1111\ 1010使用memset赋值保证最高位是负,赞美兰豆,虽然他是口糊的)
接下来枚举每个点,若为起点则将对应的ans赋为到该点的dist值;
若为终点,则用该点的ans+到该点那班车车上所花的时间值(b.dist)更新该点的dist值。
若到达p点是dist_p值小于零输出-1,若不是则输出t-dist_p。
标签:dist,idx,int,题解,ans,build,2005,Bus From: https://www.cnblogs.com/AlpacaKing-presidential-palace/p/17790402.html