PTA 应急救援站选址(floyd+打印路径)

        大学城虎溪社区有很多居民小区,居民小区道路图是连通的。现要在该社区新建一个应急救援站,且该应急救援站要和某个小区建在一起。为了使应急救援最快速,经各部门商量决定:应急救援站建好后,离应急救援站最远的小区到应急救援站的距离应该最短。
        现在你是该项目的设计者,请你根据输入的小区个数N,相邻小区间的距离W(i,j),求出应急救援站的修建地点。小区名字依次用大写英文字母A, B, C.....表示。
为了简化问题,我们约定:
1)2<=N<=20; W(i,j)<=2000, 若小区间不相邻,则用整数65535代表无穷大。
2)任意两小区之间最短路径是唯一的。
3)当存在多个满足条件的修建地点时,优先选择ASCII码较小的小区作为修建地点。

下文中的输入样例构建的无向网如下图:

image.png

输入格式:

输入为N+1行。
第一行:小区个数N
接着输入一个N行,N列的矩阵,表示N个小区间道路连接情况。

输出格式:

输出为N+1行。
第一行:应急救援站修建地点和离应急救援站最远的小区到应急救援站的最短距离

接着N行:
每行输出该修建地点到其他小区的最短路径长,以及最短路径

输入样例:

在这里给出一组输入:

6
0 10 4 8 65535 65535
10 0 5 65535 12 5
4 5 0 65535 65535 3
8 65535 65535 0 8 65535
65535  12 65535 8 0 2
65535 5 3 65535 2 0

输出样例:

在这里给出相应的输出,行末尾无空格:

A 9
0 A
9 A->C->B
4 A->C
8 A->D
9 A->C->F->E
7 A->C->F

思路:

floyd+记录路径。

方法:

floyd+拿二维表存路径:

for(ll k = 1 ; k <= n ; k ++)//floyd
	for(ll i = 1 ; i <= n ; i ++)
		for(ll j = 1 ; j <= n ; j ++)
			if(v[i][j] > v[i][k]+v[k][j])
				v[i][j] = v[i][k]+v[k][j],
				lj[i][j]=k;//记录路径

查找路径:

void dy(ll x ,ll y){//寻找路径 
	if(!lj[x][y])return;
	dy(x,lj[x][y]);//先往后找 
	cout << "->" << s[lj[x][y]];//输出路径 
	dy(lj[x][y],y);//往后找 
	return;
}

AC代码: 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl "\n"

const ll N = 1e2+7 ,M = 65535;
ll n;
ll v[N][N],lj[N][N];
string s=" ABCDEFGHIJKLMNOPQRSTUVWXYZ";

void dy(ll x ,ll y){//寻找路径 
	if(!lj[x][y])return;
	dy(x,lj[x][y]);//先往后找 
	cout << "->" << s[lj[x][y]];//输出路径 
	dy(lj[x][y],y);//往后找 
	return;
}

void solve(){
	cin >> n;
	for(ll i =  1 ; i <= n ; i ++)
		for(ll j = 1 ; j <= n ; j ++)
			cin >> v[i][j];
	memset(lj,0,sizeof lj);
	for(ll k = 1 ; k <= n ; k ++)//floyd
		for(ll i = 1 ; i <= n ; i ++)
			for(ll j = 1 ; j <= n ; j ++)
				if(v[i][j] > v[i][k]+v[k][j])
					v[i][j] = v[i][k]+v[k][j],
					lj[i][j]=k;//记录路径 
	ll w=-1,cnt=M;//寻找起始点 
	for(ll i = 1 ; i <= n ; i ++){
		ll c=0;
		for(ll j = 1 ; j <= n ; j ++)
			c=max(c,v[i][j]);
		if(c < cnt)w=i,cnt=c;
	}
	cout << s[w] << " " << cnt << endl;
	for(ll i = 1 ; i <= n ; i ++){
		cout << v[w][i] << " " << s[w];
		stack<ll>st;
		dy(w,i);//打印路径(路径没有头尾!!!) 
		if(w != i)cout <<  "->" << s[i];//输出结尾 
		cout << endl;
	}
	return ;
}

int main(){
	ll t=1;//cin >> t;
	while(t --)solve();
	return 0;
}
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值