Nuc - 00005:兔子与樱花 (Floyd求最短路+路径记录)
2017-03-22 22:06
253 查看
题目描述:
总时间限制: 1000ms 内存限制: 65535kB
描述
很久很久之前,森林里住着一群兔子。有一天,兔子们希望去赏樱花,但当他们到了上野公园门口却忘记了带地图。现在兔子们想求助于你来帮他们找到公园里的最短路。
输入输入分为三个部分。
第一个部分有P+1行(P<30),第一行为一个整数P,之后的P行表示上野公园的地点。
第二个部分有Q+1行(Q<50),第一行为一个整数Q,之后的Q行每行分别为两个字符串与一个整数,表示这两点有直线的道路,并显示二者之间的矩离(单位为米)。
第三个部分有R+1行(R<20),第一行为一个整数R,之后的R行每行为两个字符串,表示需要求的路线。
输出输出有R行,分别表示每个路线最短的走法。其中两个点之间,用->(矩离)->相隔。
样例输入
样例输出
题目思路:
题目中给定一些公园的地点,然后给出某些地点存在的路径以及路长,要求出任意的某两个地点之间的最短路,按照格式打印路径。因为是求任意两点之间的最短路。并且数据的范围并不是很大,因此采用Floyd算法。该题目的难点在于建图和路径的记录。因为题目中给出的地点是给定的字符串,而不是编号,因此我们需要使用 map来将地点编号,以方便数据的处理。在记录路径的时候,我们在更新最短路径的地方进行松弛操作。用point[i][j]的值来表示从i点出发到j点的最短路中i点的下一个结点。
题目代码:
# include <cstdio>
# include <map>
# include <iostream>
# define INF 1000000
using namespace std;
map<string, int>map1;
map<int, string>map2;
int dist[35][35];
int point[35][35];
int p, q, r, d;
string t1, t2;
void init()
{
//dist[i][j]表示i到j的最短距离
for(int i = 0; i < 35; i++){
for(int j = 0; j < 35; j++){
dist[i][j] = INF;
}
dist[i][i] = 0;
}
//point[i][j]表示从i到j的最短路线从i出发的下一个结点
for (int i=0; i<35; i++) {
for (int j=0; j<35; j++) {
point[i][j] = j;
}
}
//将地点编号
scanf("%d",&p);
for(int i = 0; i < p; i++ ){
cin>>t1;
map1[t1] = i;
map2[i] = t1;
}
//初始化距离
scanf("%d",&q);
for(int i = 0; i < q; i++ ){
cin>>t1>>t2>>d;
dist[map1[t1]][map1[t2]] = dist[map1[t2]][map1[t1]] = d;
}
}
//求出2点间最短距离
void floyd()
{
for(int k = 0; k < p; k++){
for(int i = 0; i < p; i++){
for(int j = 0; j < p; j++){
if(dist[i][j] > dist[i][k] + dist[k][j]){
dist[i][j] = dist[i][k] + dist[k][j];
//维护从i到j的最短距离从i出发的下一个结点
point[i][j] = point[i][k];
}
}
}
}
}
int main()
{
init();
floyd();
cin>>r;
while(r--){
cin>>t1>>t2;
//从起点出发的下一个结点
int k = point[map1[t1]][map1[t2]];
if(t1 != t2){
cout<<t1<<"->("<<dist[map1[t1]][k]<<")->";
while(k != map1[t2]){
cout<<map2[k]<<"->("<<dist[k][point[k][map1[t2]]]<<")->";
//更新下一结点
k = point[k][map1[t2]];
}
}
cout<<t2<<endl;
}
return 0;
}
总时间限制: 1000ms 内存限制: 65535kB
描述
很久很久之前,森林里住着一群兔子。有一天,兔子们希望去赏樱花,但当他们到了上野公园门口却忘记了带地图。现在兔子们想求助于你来帮他们找到公园里的最短路。
输入输入分为三个部分。
第一个部分有P+1行(P<30),第一行为一个整数P,之后的P行表示上野公园的地点。
第二个部分有Q+1行(Q<50),第一行为一个整数Q,之后的Q行每行分别为两个字符串与一个整数,表示这两点有直线的道路,并显示二者之间的矩离(单位为米)。
第三个部分有R+1行(R<20),第一行为一个整数R,之后的R行每行为两个字符串,表示需要求的路线。
输出输出有R行,分别表示每个路线最短的走法。其中两个点之间,用->(矩离)->相隔。
样例输入
6 Ginza Sensouji Shinjukugyoen Uenokouen Yoyogikouen Meijishinguu 6 Ginza Sensouji 80 Shinjukugyoen Sensouji 40 Ginza Uenokouen 35 Uenokouen Shinjukugyoen 85 Sensouji Meijishinguu 60 Meijishinguu Yoyogikouen 35 2 Uenokouen Yoyogikouen Meijishinguu Meijishinguu
样例输出
Uenokouen->(35)->Ginza->(80)->Sensouji->(60)->Meijishinguu->(35)->Yoyogikouen Meijishinguu
题目思路:
题目中给定一些公园的地点,然后给出某些地点存在的路径以及路长,要求出任意的某两个地点之间的最短路,按照格式打印路径。因为是求任意两点之间的最短路。并且数据的范围并不是很大,因此采用Floyd算法。该题目的难点在于建图和路径的记录。因为题目中给出的地点是给定的字符串,而不是编号,因此我们需要使用 map来将地点编号,以方便数据的处理。在记录路径的时候,我们在更新最短路径的地方进行松弛操作。用point[i][j]的值来表示从i点出发到j点的最短路中i点的下一个结点。
题目代码:
# include <cstdio>
# include <map>
# include <iostream>
# define INF 1000000
using namespace std;
map<string, int>map1;
map<int, string>map2;
int dist[35][35];
int point[35][35];
int p, q, r, d;
string t1, t2;
void init()
{
//dist[i][j]表示i到j的最短距离
for(int i = 0; i < 35; i++){
for(int j = 0; j < 35; j++){
dist[i][j] = INF;
}
dist[i][i] = 0;
}
//point[i][j]表示从i到j的最短路线从i出发的下一个结点
for (int i=0; i<35; i++) {
for (int j=0; j<35; j++) {
point[i][j] = j;
}
}
//将地点编号
scanf("%d",&p);
for(int i = 0; i < p; i++ ){
cin>>t1;
map1[t1] = i;
map2[i] = t1;
}
//初始化距离
scanf("%d",&q);
for(int i = 0; i < q; i++ ){
cin>>t1>>t2>>d;
dist[map1[t1]][map1[t2]] = dist[map1[t2]][map1[t1]] = d;
}
}
//求出2点间最短距离
void floyd()
{
for(int k = 0; k < p; k++){
for(int i = 0; i < p; i++){
for(int j = 0; j < p; j++){
if(dist[i][j] > dist[i][k] + dist[k][j]){
dist[i][j] = dist[i][k] + dist[k][j];
//维护从i到j的最短距离从i出发的下一个结点
point[i][j] = point[i][k];
}
}
}
}
}
int main()
{
init();
floyd();
cin>>r;
while(r--){
cin>>t1>>t2;
//从起点出发的下一个结点
int k = point[map1[t1]][map1[t2]];
if(t1 != t2){
cout<<t1<<"->("<<dist[map1[t1]][k]<<")->";
while(k != map1[t2]){
cout<<map2[k]<<"->("<<dist[k][point[k][map1[t2]]]<<")->";
//更新下一结点
k = point[k][map1[t2]];
}
}
cout<<t2<<endl;
}
return 0;
}
相关文章推荐
- 兔子与樱花(map+最短路+记录路径)
- T001:兔子与樱花 最短路及路径
- HDOJ 1385 Minimum Transport Cost (最短路 Floyd & 路径记录)
- C++实现带路径记录的Floyd-Warshall算法
- hdu 1385 Minimum Transport Cost(最短路,floyd打印字典序路径)
- HDOJ 题目1595 find the longest of the shortest(枚举,最短路记录路径)
- 兔子与樱花---每对结点的最短路径
- hdu 1385(zoj 1456)Minimum Transport Cost(最短路,输出路径,Floyd实现)
- hdu-1385-floyd记录路径
- 图论---最短路(记录路径)
- L2-001. 紧急救援(最短路dij+路径记录)(模板)
- HDU ACM 3986 Harry Potter and the Final Battle(邻接表实现最短路dijkstra堆优化记录路径 + 枚举最短路上每条边)
- HDU 1385 Minimum Transport Cost(floyd)(记录路径)
- HDU 1385 Minimum Transport Cost (Floyd求最短路径+记录字典序路径)
- 最短路记录路径——PKU 2457
- 兔子与樱花(floyd+打印路径)
- L2-001. 紧急救援(PAT 最短路+记录路径)
- shuoj-小6爱夜跑--Floyd记录多个最短路径
- HDU 1385【两点间最短路, DIJK + 记录路径】
- 偷西瓜(SPFA运用链式前向星来记录路径+删除路径+求最短路和次短路)