Description
Problem gToll! Revisited
Input:Standard Input
Output:Standard output
Time limit:1 second
Sindbad the sailor sold66Silver Spoons to the Sultan of Samarkand. the selling was quite easy; but delivering was complicated. the items were transported over land, passing through several towns and ages. each Town and Village demanded an entry toll. there were no tolls for leaving. the toll for entering a village was simply one item. the toll for enteringTownWas one piece per20Items carried. For example, to enter a town carrying70Items, you had to pay4Items as toll. The towns and ages were situated strategically between rocks, swamps and rivers, So you cocould not avoid them.
| |
Figure 1: to reach Samarkand66Spoons, traveling through a town followed by two ages, you must start76Spoons. |
|
|
Figure 2: the best route to reachXWith39Spoons, starting fromA, IsA-> B-> C-> X, Shown with arrows in the figure on the left. The best route to reachXWith10Spoons isA-> D-> X, Shown in the figure on the right. The figures display towns as squares and ages as circles. |
Predicting the tolls charged in each village or town is quite simple, but finding the best route (the cheapest route) is a real challenge. the best route depends upon the number of items carried. for numbers up20, Ages and towns charge the same. For large numbers of items, it makes sense to avoid towns and travel through more ages, as your strated in figure2.
You must write a program to solve Sindbad's problem. given the number of items to be delivered to a certain town or village and a road map, your program must determine the total number of items required at the beginning of the journey that uses a cheapest route. you will also have to find the cheapest route. if there is more than one such route, print the lexicographically smallest one (A-n-dIs smallerA-n-d).
Input
The input consists of several test cases. Each test case consists of two parts: the roadmap followed by the delivery details.
The first line of the roadmap contains an integerN, Which is the number of roads in the map(0 <=N). Each of the nextNLines contains exactly two letters representing the two endpoints of a road. A capital letter represents a town; a lower case letter represents a village. roads can be traveled in either direction.
Following the roadmap is a single line for the delivery details. This line consists of three things: an integerP (0 <p <1000000000)For the number of items that must be delivered, a letter for the starting place, and a letter for the place of delivery. The roadmap is always such that the items can be delivered.
The last test case is followed by a line containing the number-1.
Output
The output consists of three lines for each test case. first line displays the case number, second line shows the number of items required at the beginning of the journey and third line shows the path according to the problem statement above. actually, the path contains all the city/village names that Sindbad sees along his journey. two consecutive city/village names in the path are separated by a hyphen.
Sample input output for sample input
1 A Z 19 A Z 5 A D D x A B B c C x 39 A x -1 |
Case 1: 20 A-z Case 2: 44A-B-c-x |
A: transportation of goods requires a toll. To enter a village, you need to pay a unit of goods. To enter a town, you need 1/20 units. Here are the start and end points for you, ask you to find a route with the least traffic fees. If there are more than one route, You Need To lexicographically
Train of Thought: Push the shortest Short Circuit in the reverse direction. The pitfall is the boundary processing, instead of 20 but 19. If you are looking for a lexicographically ordered word, the smaller the ASCII value, the smaller the ASCII value.
#include<cstdio>#include<cmath>#include<ctype.h>#include<vector>#include<cstring>using namespace std;const int maxn = 55;typedef long long ll;const ll INF = 1ll<<62;vector<int> G[maxn];bool vis[maxn];ll dis[maxn];void dijkstra(int s, int e, ll x, int n) {for (int i = 1; i <= n; i++)dis[i] = INF;dis[s] = x;memset(vis, 0, sizeof(vis));for (int i = 0; i < n; i++) {int index;ll Min = INF;for (int j = 1; j <= n; j++)if (!vis[j] && dis[j] < Min) {Min = dis[j];index = j;}if (Min == INF)break;vis[index] = 1;for (int j = 0; j < G[index].size(); j++) {ll tmp;if (index < 27)tmp = (ll) ceil(dis[index]/19.0);else tmp = 1;if (dis[index]+tmp < dis[G[index][j]] && !vis[G[index][j]])dis[G[index][j]] = dis[index]+tmp;}}}int main() {int n;int u, v;int cas = 1;ll x;char s[10], e[10];while (scanf("%d", &n) != EOF && n != -1) {for (int i = 1; i <= 52; i++)G[i].clear();for (int i = 0; i < n; i++) {scanf("%s%s", s, e);if (isupper(s[0]))u = s[0] - 'A' + 1;else u = s[0] - 'a' + 27;if (isupper(e[0]))v = e[0] - 'A' + 1;else v = e[0] - 'a' + 27;G[u].push_back(v);G[v].push_back(u);}scanf("%lld%s%s", &x, s, e);if (isupper(s[0]))u = s[0] - 'A' + 1;else u = s[0] - 'a' + 27;if (isupper(e[0]))v = e[0] - 'A' + 1;else v = e[0] - 'a' + 27;dijkstra(v, u, x, 52);printf("Case %d:\n", cas++);printf("%lld\n", dis[u]);printf("%c", s[0]);int cur = u;while (cur != v) {int Min = 100;for (int j = 0; j < G[cur].size(); j++) {ll tmp;if (G[cur][j] < 27)tmp = (ll) ceil(dis[cur]/20.0);else tmp = 1;if (dis[cur]-tmp == dis[G[cur][j]] && Min > G[cur][j]) Min = G[cur][j];}cur = Min;printf("-%c", cur<27?(cur-1+'A'):(cur-27+'a'));}printf("\n");}return 0;}