【UVA10537】The 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