标签:p2 int 多校 相邻 spfa 打卡 include 2017 dp
题目描述
在ZJU,每个学生都被要求课外跑步,并且需要跑够一定的距离 K ,否则体育课会挂科。
ZJU有4个打卡点,分别标记为 p1,p2,p3,p4 。每次你到达一个打卡点,你只需要刷一下卡,系统会自动计算这个打卡点和上一个打卡点的距离,并将它计入你的已跑距离。
系统把这4个打卡点看成一个环。 p1 与 p2 相邻、 p2 与 p3 相邻、 p3 与 p4 相邻、 p4 与 p1 相邻。当你到达打卡点 pi 时,你只能跑到与该打卡点相邻的打卡点打卡。
打卡点 p2 是离宿舍最近的一个打卡点。CJB总是从 p2 出发,并回到 p2 。因为CJB很圆,所以他希望他跑的距离不少于 K ,但又要尽量小。
题解
取 d=min(dis1-2,dis2-3),那么对于每种方案,均可以通过往返跑 d 这条边使得距离增加 2d
令 w=2d,dp[i][j] 表示从起点出发到达 i ,距离模 w 为 j 时的最短路,这个由 spfa 可求得,时间复杂度为 O(w logw)
最后,我们由 dp[p2][j] 即可求出最优路线(具体见图)
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; typedef long long ll; int t,w,d[4],inque[4][60001]; ll k,dp[4][60001]; struct que{int p,m;}; queue<que> q; int main(){ scanf("%d",&t); while(t--){ scanf("%lld%d%d%d%d",&k,&d[0],&d[1],&d[2],&d[3]); w=2*min(d[0],d[1]); memset(dp,0x7f,sizeof(dp)); dp[1][0]=0; q.push((que){1,0}); inque[1][0]=1; while(!q.empty()){ int p=q.front().p; int m=q.front().m; int nxt=(p+1)%4; int pre=(p+3)%4; q.pop(); inque[p][m]=false; if(dp[p][m]+d[p]<dp[nxt][(m+d[p])%w]){ dp[nxt][(m+d[p])%w]=dp[p][m]+d[p]; if(!inque[nxt][(m+d[p])%w]){ q.push((que){nxt,(m+d[p])%w}); inque[nxt][(m+d[p])%w]=1; } } if(dp[p][m]+d[pre]<dp[pre][(m+d[pre])%w]){ dp[pre][(m+d[pre])%w]=dp[p][m]+d[pre]; if(!inque[pre][(m+d[pre])%w]){ q.push((que){pre,(m+d[pre])%w}); inque[pre][(m+d[pre])%w]=1; } } } while(dp[1][k%w]>k)k++; printf("%lld\n",k); } return 0; }
标签:p2,int,多校,相邻,spfa,打卡,include,2017,dp 来源: https://www.cnblogs.com/HarryPotter-fan/p/11358502.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。