1 条题解
-
0
自动搬运
来自洛谷,原作者为

logfk
不是哥们,退役了还看啊搬运于
2025-08-24 22:31:54,当前版本为作者最后更新于2021-07-20 16:28:58,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题意
题意可直接转化为:
每天共有 个小时,每走一条路会消耗一定小时,用尽后或大于剩余时间当天将不能再走。
以及,奇数天走路的正方向,偶数天走路的反方向,求从起点到终点所用最短时间(优先天数,天数相同比较当天剩余时间)时的路径。
样例为:
第一天:。
第二天:留在 。
第三天:。
分析
如果想要保证走的时间最短,就应该使用最短路,我们从一个点出发到一个点时,以天数为第一关键字,当前天数所剩时间为第二关键字进行优先队列的标准进行 Dij,如果当前天的时间加上走这条的时间小于等于 则可以转移,如果大于则无法转移。
但是这并不能覆盖样例的等候情况,因此我们需要判断是否能够在一个地点等一天,所以我们直接在判断之后进行一次下一天的过渡,在转移过程中记录相关信息,最后到终点时直接输出即可。
代码
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-f; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } struct node{ int da,ti,np; friend bool operator < (node x,node y) { if(x.da==y.da) return x.ti>y.ti; return x.da>y.da; } };//天数,天数相同比较时间 priority_queue<node> q; int hpla[110],st,to[2010],nxt[2010],head[2010],val[2010],fl[2010],cnt,vis[110][2][20],pre[110],hpt[110],hpti[110]; int ansp[110],ansx[110],anst[110],ansti[110]; void addedge(int x,int y,int z,int ff) { to[++cnt]=y; nxt[cnt]=head[x]; head[x]=cnt; val[cnt]=z; fl[cnt]=ff;//正图还是反图 } void out(int x,int &nc) { // cout<<x<<nc<<endl; // if(x==0) return; ansp[nc]=pre[x]; ansx[nc]=x; anst[nc]=hpt[x]; ansti[nc]=hpti[x];//取出路径 nc++; if(pre[x]==st) return; out(pre[x],nc); } int main() { int x,y,z;st=read(); int ed=read(),n=read(),m=read(); memset(hpt,0x3f,sizeof(hpt)); memset(hpti,0x3f,sizeof(hpti)); for(int i=1;i<=m;i++) { x=read(),y=read(),z=read(); addedge(x,y,z,1); addedge(y,x,z,0); } vis[st][1][0]=1; q.push((node){1,0,st}); while(!q.empty()) { node nq=q.top(); q.pop(); // cout<<nq.np<<" "<<nq.da<<" "<<nq.ti<<endl; if(nq.np==ed)//到了直接输出 { int cc=0; out(nq.np,cc); for(int i=cc-1;i>=0;i--) { cout<<ansp[i]<<" "<<ansx[i]<<" "<<anst[i]<<" "<<ansti[i]<<endl; } return 0; } x=nq.np; int d=nq.da,tt=nq.ti; for(int i=head[x];i;i=nxt[i]) { int ft=to[i],ro=val[i]; if(tt+ro<=12)//如果一天还未结束 { // cout<<ft<<" "<<ro<<endl; if(!vis[ft][d%2][tt+ro]&&d%2==fl[i])//当前时间没有走过 { if(d<hpt[ft]||(d==hpt[ft]&&tt+ro<hpla[ft]))//剩余时间更优 { pre[ft]=x; hpt[ft]=d; hpti[ft]=ro; hpla[ft]=ro+tt; } vis[ft][d%2][tt+ro]=1; q.push((node){d,tt+ro,ft}); } } } if(!vis[x][(d+1)%2][0])//注意!可以选择在某个地方停留一天 { q.push((node){d+1,0,x}); } } }
- 1
信息
- ID
- 6837
- 时间
- 1000ms
- 内存
- 500MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者