【UVA10537】The Toll! Revisited
来源:互联网 发布:小程序跳转到淘宝app 编辑:程序博客网 时间:2024/05/14 22:22
题意
给定图
G=(V,E) ,V 中有两类点,一类点(A 类)在进入时要缴纳1的费用,另一类点(B 类)在进入时要缴纳当前携带金额的120 (不足20的部分按20算)
已知起点为S ,终点为T ,希望在到达T 时能够拥有P 的金额,问一开始在S 最少要携带多少金额,并求出路径(若有多条,输出字典序最小的)
从S 离开时不需要缴费,进入T 时需要缴费
解法
spfa 变异最短路:
其实这道题的难点就在于怎么求出花费,其他的过程则和正常的spfa 一模一样,至于输出路径就记一个Pre 即可
考虑一条从T 到S 的路径,假设当前点为u ,要前往的点为v ,那么按u 的种类分情况讨论:
如果u 为A 类点,那么从u 前往v 的花费显然是disu+1
如果u 为B 类点,那么从u 前往v 花费就是:x=disu∗2019,while(x−x+1920<disu)x ++,最后的x 就是从u 到v 的花费,不过下面的代码不是这么写的,比较鬼畜……
然后倒着做spfa 即可
复杂度
O(
|V|∗|E| )
代码
#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<queue>#define Rint register int#define Lint long long intusing namespace std;const Lint INF=1e18;const int E=50010;const int N=1010;struct node{ int next,from,to;}t[E];int head[N],num;int Pre[N],vis[N];Lint dis[N];int n,S,T;Lint p;queue<int> q;void add(int u,int v){ t[++num]=(node){ head[u],u,v }; head[u]=num;}Lint cal(Lint w){ Lint u,num,y; u=w%20; if( !u ) u=w/20; else u=w/20+1; num=u*20; while( w+u>num ) { y=(w+u)%20; u= !y ? (w+u)/20 : (w+u)/20+1 ; num=u*20; } return u;}void spfa(){ int tmp; for(int i=1;i<=120;i++) dis[i]=INF,Pre[i]=vis[i]=0; dis[T]=p,q.push( T ); while( !q.empty() ) { tmp=q.front(),q.pop(); vis[tmp]=0; for(int i=head[tmp],x; i ;i=t[i].next) { x=t[i].to; if( tmp>=27 && ( dis[x]>dis[tmp]+1 || ( dis[x]==dis[tmp]+1 && t[Pre[x]].from>tmp ) ) ) { dis[x]=dis[tmp]+1; Pre[x]=i; if( !vis[x] ) vis[x]=1,q.push( x ); } if( tmp<=26 && ( dis[x]>dis[tmp]+cal( dis[tmp] ) || ( dis[x]==dis[tmp]+cal( dis[tmp] ) && t[Pre[x]].from>tmp ) ) ) { dis[x]=dis[tmp]+cal( dis[tmp] ); Pre[x]=i; if( !vis[x] ) vis[x]=1,q.push( x ); } } } printf("%lld\n",dis[S]); printf("%c",S-1+'A'); for(int i=t[Pre[S]].from; i ;i=t[Pre[i]].from) printf("-%c",i-1+'A'); printf("\n");}int main(){ char a[10],b[10]; int u,v,C=0; while( scanf("%d",&n)!=EOF ) { if( n==-1 ) break ; num=0; memset( head,0x0,sizeof head ); for(int i=1;i<=n;i++) { scanf("%s%s",a,b); u=a[0]-'A'+1,v=b[0]-'A'+1; add( u,v ),add( v,u ); } scanf("%lld%s%s",&p,a,b); S=a[0]-'A'+1,T=b[0]-'A'+1; printf("Case %d:\n",++C); spfa(); } return 0;}
阅读全文
0 0
- 【UVA10537】The Toll! Revisited
- UVA10537 Toll! Revisited
- UVa10537 Toll! Revisited
- UVA10537[The Toll! Revisited] dijkstra/spfa 反向建图
- Uva-10537-The Toll! Revisited
- UVa 10537 - The Toll! Revisited
- Uva 10537 The Toll! Revisited
- uva 10537/The Toll! Revisited
- UVA - 10537 The Toll! Revisited dijkstra反向
- UVA 10537 The Toll! Revisited(最短路变形)
- uva 10537 - The Toll! Revisited (逆向思维最短路)
- UVA - 10537 The Toll! Revisited (最短路变形逆推)
- UVA 10537 - The Toll! Revisited(dijstra扩展)
- UVa - 10537 - The Toll! Revisited(单源最短路)
- uva 10537 - The Toll! Revisited(最短路)
- UVa 10537 The Toll! Revisited! Dijkstra最短路
- UVA 10537 The Toll! Revisited(最短路变形+输出字典序最小路径)
- uva 10537 - The Toll! Revisited (逆向思维+最短路+输出字典序最小路径)
- Coursera-Deep Learning Specialization 课程之(一):Neural Networks and Deep Learning-weak4编程作业
- Linux基础学习篇6
- java技能图谱
- [P1351][NOIP2014]联合权值
- java学习笔记 20171017 dynamic web module 更改为高版本失败
- 【UVA10537】The Toll! Revisited
- c开发笔试题
- 1.Nginx修改进程名称
- JavaScript中原型对象的彻底理解
- 银河麒麟服务器操作系统常用问题及解决方案
- MISARC 协议规范
- coredump简介与coredump原因总结
- Session
- Struts2入门学习(一)