2021-06-22

兔子与樱花
查看提交统计提问总时间限制: 1000ms 内存限制: 65535kB描述很久很久之前,森林里住着一群兔子。有一天,兔子们希望去赏樱花,但当他们到了上野公园门口却忘记了带地图。现在兔子们想求助于你来帮他们找到公园里的最短路。输入输入分为三个部分。第一个部分有P+1行(P<30),第一行为一个整数P,之后的P行表示上野公园的地点。第二个部分有Q+1行(Q<50),第一行为一个整数Q,之后的Q行每行分别为两个字符串与一个整数,表示这两点有直线的道路,并显示二者之间的矩离(单位为米)。第三个部分有R+1行(R<20),第一行为一个整数R,之后的R行每行为两个字符串,表示需要求的路线。输出输出有R行,分别表示每个路线最短的走法。其中两个点之间,用->(矩离)->相隔。样例输入6GinzaSensoujiShinjukugyoenUenokouenYoyogikouenMeijishinguu6Ginza Sensouji 80Shinjukugyoen Sensouji 40Ginza Uenokouen 35Uenokouen Shinjukugyoen 85Sensouji Meijishinguu 60Meijishinguu Yoyogikouen 352Uenokouen YoyogikouenMeijishinguu Meijishinguu样例输出Uenokouen->(35)->Ginza->(80)->Sensouji->(60)->Meijishinguu->(35)->YoyogikouenMeijishinguu
解题代码及注释如下

# include <cstdio>
# include <map>
# include <iostream>
# define INF 1000000
using namespace std;
//弗洛伊德(floyed)遍历每一对顶点,看看是否有一个顶点让这对顶点距离最小 
// map是STL的一个关联容器 

map<string, int>map1;//通过地名找到序号 
map<int, string>map2;//通过序号找到地名 
 //定义了一个用int作为索引,并拥有相关联的指向string的指针 
int dist[35][35];
int path[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;
	}//初始化 
	//path[i][j]表示从i到j的最短路线从i出发的下一个结点 
	for (int i=0; i<35; i++)  {  
        for (int j=0; j<35; j++)  {  
            path[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;//两者距离 
	}
	
}
//求出两点间最短距离 
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出发的下一个结点 
					path[i][j] = path[i][k];
				}
			}
		}
	}	
}
 
int main()
{
	init();
	floyd();
	cin>>r;
	while(r--){
		cin>>t1>>t2;
		//从起点出发的下一个结点 
		int k = path[map1[t1]][map1[t2]];
		if(t1 != t2){
			cout<<t1<<"->("<<dist[map1[t1]][k]<<")->";
			
			while(k != map1[t2]){
				cout<<map2[k]<<"->("<<dist[k][path[k][map1[t2]]]<<")->";
				//更新下一结点 
				k = path[k][map1[t2]];
			}
		}
		cout<<t2<<endl;//两者同一处 
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值