您的位置:首页 > 其它

UVA - 10537 The Toll! Revisited dijkstra反向

2016-07-24 11:20 232 查看
Sindbad the Sailor sold 66 silver spoons to the Sultan of Samarkand. The selling was quite easy; butdelivering was complicated. The items were transported over land, passing through several towns andvillages. Each town and village demanded an entry toll.
There were no tolls for leaving. The toll forentering a village was simply one item. The toll for entering a town was one piece per 20 items carried.For example, to enter a town carrying 70 items, you had to pay 4 items as toll. The towns and villageswere
situated strategically between rocks, swamps and rivers, so you could not avoid them.Figure 1: To reach Samarkand with 66 spoons, traveling through a town followed by two villages, youmust start with 76 spoons.Figure 2: The best route to reach X with 39 spoons,
starting from A, is A→b→c→X, shown witharrows in the figure on the left. The best route to reach X with 10 spoons is A→D→X, shown in thefigure on the right. The figures display towns as squares and villages as circles.Predicting the tolls charged in each village
or town is quite simple, but finding the best route (thecheapest route) is a real challenge. The best route depends upon the number of items carried. Fornumbers up to 20, villages and towns charge the same. For large numbers of items, it makes sense toavoid
towns and travel through more villages, as illustrated in Figure 2.You must write a program to solve Sindbads problem. Given the number of items to be deliveredto a certain town or village and a road map, your program must determine the total number of itemsrequired
at the beginning of the journey that uses a cheapest route. You will also have to find thecheapest route. If there is more than one such route, print the lexicographically smallest one (A-n-d issmaller than a-n-d).InputThe input consists of several test cases.
Each test case consists of two parts: the roadmap followed bythe delivery details.The first line of the roadmap contains an integer n, which is the number of roads in the map(0 ≤ n). Each of the next n lines 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 ineither direction.Following the roadmap is a single line for the delivery details. This line consists of three things:an integer p (0 <
p < 1000000000) for the number of items that must be delivered, a letter for thestarting place, and a letter for the place of delivery. The roadmap is always such that the items can bedelivered.The last test case is followed by a line containing the number
‘-1’.OutputThe output consists of three lines for each test case. First line displays the case number, second lineshows the number of items required at the beginning of the journey and third line shows the pathaccording to the problem statement above. Actually,
the path contains all the city/village names thatSindbad sees along his journey. Two consecutive city/village names in the path are separated by ahyphen.

喵的题目粘贴的屎一样,不管了,题目意思大概就是给一个图,节点分为大小字母,每经过一个大写节点会收取1/20的当前钱数,经过小写节点会收取1元,要求最后到达重点的钱数,问最少在起点带多少钱。

给终点求起点,第一反应就是起点终点互换求最短路。用邻接表保存,处理每到一个节点的所需金额即可。

用pre数组存一下前驱输出路径。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<vector>
using namespace std;
typedef long long ll;
const ll inf=1LL<<60;
char s1[2],s2[2];
vector<int> mp[210];
ll dis[210];
bool vis[210];
int pre[210];
ll sum;
ll calc(char x)
{
if(islower(x)) return dis[x]+1;
else
{
ll tmp=ceil(dis[x]*20*1.0/19);
return tmp;
}
}
void dijkstra(int start,int ed)
{
for(int i=0;i<210;i++)
{
dis[i]=inf;
vis[i]=0;
pre[i]=-1;
}
dis[start]=sum;
vis[start]=1;
for(int i=0;i<mp[start].size();i++)
{
dis[mp[start][i]]=calc(start);
pre[mp[start][i]]=start;
}
for(int i=0;i<200;i++)
{
ll minn=inf;
int t=-1;
for(int j=1;j<=200;j++)
{
if(!vis[j]&&dis[j]<minn)
{
minn=dis[j];
t=j;
}
}
if(t!=-1)
{
vis[t]=1;
ll cost=calc(t);
for(int j=0;j<mp[t].size();j++)
{
if(!vis[mp[t][j]]&&dis[mp[t][j]]>cost)
{
pre[mp[t][j]]=t;
dis[mp[t][j]]=cost;
}
}
}
}
}
int main()
{
int tt=0;
int n;
while(scanf("%d",&n)!=EOF&&n!=-1)
{
for(int i='A';i<='Z';i++)
mp[i].clear();
for(int i='a';i<='z';i++)
mp[i].clear();
for(int i=0;i<n;i++)
{
scanf("%s %s",s1,s2);
mp[s1[0]].push_back(s2[0]);
mp[s2[0]].push_back(s1[0]);
}
scanf("%d %s %s",&sum,s1,s2);
dijkstra(s2[0],s1[0]);
printf("Case %d:\n",++tt);
printf("%lld\n",dis[s1[0]]);
printf("%c",s1[0]);
int u=s1[0];
while(pre[u]!=-1)
{
u=pre[u];
printf("-%c",u);
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dijkstra 最短路