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