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;
}
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;
}
相关文章推荐
- 基于Java实现的Dijkstra算法示例
- Dijkstra和floyd——求单源点最短路径
- 初学图论-Dijkstra单源最短路径算法
- 初学图论-Dijkstra单源最短路径算法基于优先级队列(Priority Queue)的实现
- Dijkstra算法的粗略学习
- Hdu2066(一个人的旅行)
- 【日常练习 dijkstra】POJ 2387 Til the Cows Come Home
- 只有5行的Floyd算法!!!
- 【高手回避】poj3268,一道很水的dijkstra算法题
- poj2387 Til the Cows Come Home—Dijkstra模板
- YEN算法和删除算法分别实现K可靠最短路径算法
- Dijkstra 算法实现及问题
- Djkstra
- 最短路
- 一个人的旅行
- HDU 2544
- pat甲级_路径问题(例题:pat 1003 Emergency (25))
- 文章标题
- Poj2638 网络流+最短路+二分答案
- Aizu1311 分层图最短路 (...大概)