1:兔子与樱花
总时间限制: 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
这是一道求任意两点最短路径+打印路径的题,由于本题数据小,所以我用记忆化深搜加回溯做的,代码如下
#include<bits/stdc++.h>
using namespace std;
map<string,int> mp1;
map<int,string> mp2;
int t,n,m,a,x,y,ans=9999999,w=-1;
string s1,s2;
int s[35][35]= {0},u[35]= {0};
int d[35],p[35];//memset(s,0,sizeof(s));//d为最终求得的最短路,p记录搜索过程中的路径
void Dfs(int x,int h,int num) {if(x==y) {if(num<ans) {//更新路径for(int i=0; i<h; i++)d[i]=p[i];w=h;ans=num;return ;}}for(int i=1; i<=t; i++) {if(s[x][i]!=0&&num+s[x][i]<ans&&u[i]==0) {//num+s[x][i]<ans,枝剪p[h++]=i;u[i]=1;num+=s[x][i];Dfs(i,h,num);h--;u[i]=0;num-=s[x][i];//回溯}}
}
int main() {cin >> t;for(int i=1; i<=t; i++) {cin >> s1;mp1[s1]=i;mp2[i]=s1;}cin >> n;while(n--) {cin >> s1 >> s2 >> a;s[mp1[s1]][mp1[s2]]=a;s[mp1[s2]][mp1[s1]]=a;}cin >> m;while(m--) {ans=9999999,w=-1;cin >> s1 >> s2;x=mp1[s1],y=mp1[s2];memset(d,0,sizeof(d));memset(p,0,sizeof(p));memset(u,0,sizeof(u));
// for(int i=1;i<=t;i++){
// for(int j=1;j<=t;j++)
// cout << s[i][j] << " ";
// cout << endl;
// }Dfs(x,0,0);cout << s1;for(int i=0; i<w; i++) {if(i==0)cout << "->(" << s[x][d[i]] << ")->" << mp2[d[i]];elsecout << "->(" << s[d[i-1]][d[i]] << ")->" << mp2[d[i]];}cout << endl;}return 0;
}
其实本题可以用佛洛伊德算法更好的解决,时间复杂度更低,可以参考以下代码
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;int n,m,k;
string a[66];
int step[66][66],g[66][66];
map<string,int>mp;
const int inf=0x3f3f3f3f;
int s,e;void init()
{for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){g[i][j]=(i==j?0:inf);step[i][j]=j;}}} void floyd(){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){for(int k=1;k<=n;k++){if(g[j][k]>g[j][i]+g[i][k]){g[j][k]=g[j][i]+g[i][k];step[j][k]=step[j][i];}}} }}
void display()
{cout<<a[s];int k=s;while(k!=e){cout<<"->("<<g[k][step[k][e]]<<")->"<<a[step[k][e]];k=step[k][e];}cout<<endl;
}
int main()
{cin>>n;for(int i=1;i<=n;i++){cin>>a[i];mp[a[i]]=i;}init();cin>>m;for(int i=1;i<=m;i++){string s1,s2;int d;cin>>s1>>s2>>d;g[mp[s1]][mp[s2]]=g[mp[s2]][mp[s1]]=d;} floyd();cin>>k;while(k--){string s1,s2;cin>>s1>>s2;s=mp[s1];e=mp[s2];display();}return 0;
}