UVA10537The Toll! Revisited (逆推最短路)
Posted konjak魔芋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA10537The Toll! Revisited (逆推最短路)相关的知识,希望对你有一定的参考价值。
题目:
Sample Input
1
a Z
19 a Z
5
A D
D X
A b
b c
c X
39 A X
-1
Sample Output
Case 1:
20
a-Z
Case 2:
44
A-b-c-X
题意:
有两种节点,一种是大写字母,一种是小写字母。首先输入m条边,当经过小写字母时需要付一单位的过路费,当经过大写字母时,要付当前财务的1/20做过路费(向上取整)。问在起点最少需要带多少物品使到达终点时还有k个物品。当有多条符合条件的路径时输出字典序最小的一个。
分析:
逆推进行最短路,输出时顺序输出并选择最小字典序即可。(超级讨厌字符输入有没有,TAT,RE好多遍,记得要long long)
代码如下:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 using namespace std; 9 #define Maxn 10100 10 #define LL long long 11 12 int s,e; 13 14 struct node 15 { 16 int x,y,next; 17 }t[2*10*Maxn];int len; 18 19 int first[Maxn]; 20 LL dis[Maxn]; 21 bool inq[Maxn]; 22 23 queue<int > q; 24 25 void ins(int x,int y) 26 { 27 t[++len].x=x;t[len].y=y; 28 t[len].next=first[x];first[x]=len; 29 } 30 31 int mymin(int x,int y) {return x<y?x:y;} 32 33 void spfa(int s,int w) 34 { 35 memset(dis,127,sizeof(dis)); 36 memset(inq,0,sizeof(inq)); 37 while(!q.empty()) q.pop(); 38 dis[s]=w;inq[s]=1;q.push(s); 39 while(!q.empty()) 40 { 41 int x=q.front();q.pop();inq[x]=0; 42 LL now; 43 if(x>26) now=dis[x]+1; 44 else now=(LL)ceil(dis[x]*1.0*20/19); 45 for(int i=first[x];i;i=t[i].next) 46 { 47 int y=t[i].y; 48 if(dis[y]>now) 49 { 50 dis[y]=now; 51 if(!inq[y]) 52 { 53 q.push(y); 54 inq[y]=1; 55 } 56 } 57 } 58 } 59 } 60 61 void pri(int x) 62 { 63 if(x>26) printf("%c",x-27+\'a\'); 64 else printf("%c",x-1+\'A\'); 65 66 } 67 void ffind(int x,int z) 68 { 69 pri(x); 70 if(x==z) return;printf("-"); 71 int mn=100; 72 LL a,b; 73 a=dis[x]-1; 74 b=dis[x]-(LL)ceil(dis[x]*1.0/20); 75 for(int i=first[x];i;i=t[i].next) 76 { 77 int y=t[i].y; 78 if(y==x) continue; 79 LL now; 80 if(y<=26) now=b; 81 else now=a; 82 if(now==dis[y]) mn=mymin(mn,y); 83 } 84 if(mn<100) ffind(mn,z); 85 } 86 87 int main() 88 { 89 int n,kase=0; 90 while(1) 91 { 92 scanf("%d",&n);getchar(); 93 if(n==-1) break; 94 char a,b,c; 95 int x,y; 96 memset(first,0,sizeof(first)); 97 len=0; 98 for(int i=1;i<=n;i++) 99 { 100 scanf("%c%c%c",&a,&c,&b);getchar(); 101 if(a>=\'a\'&&a<=\'z\') x=a-\'a\'+27; 102 else x=a-\'A\'+1; 103 if(b>=\'a\'&&b<=\'z\') y=b-\'a\'+27; 104 else y=b-\'A\'+1; 105 ins(x,y);ins(y,x); 106 } 107 int p;scanf("%d%c%c%c%c",&p,&c,&a,&c,&b);getchar(); 108 if(a>=\'a\'&&a<=\'z\') x=a-\'a\'+27; 109 else x=a-\'A\'+1; 110 if(b>=\'a\'&&b<=\'z\') y=b-\'a\'+27; 111 else y=b-\'A\'+1; 112 spfa(y,p); 113 printf("Case %d:\\n",++kase); 114 printf("%lld\\n",dis[x]); 115 ffind(x,y);printf("\\n"); 116 } 117 return 0; 118 }
2016-04-06 13:35:13
以上是关于UVA10537The Toll! Revisited (逆推最短路)的主要内容,如果未能解决你的问题,请参考以下文章
UVA10537The Toll! Revisited (逆推最短路)
P2966 [USACO09DEC]牛收费路径Cow Toll Paths
REVISIT:如何在msys2 / mintty中配置默认 Shell?