题意:
给定n个城市,c个目的地(可能有重合的),r条有向边。
接下来是出发点,然后是c个目的地。
接下来r行是路径的信息,箭头代表方向。
求每次从出发点出发到达目的地,然后再回到起点。走c个来回的最短路之和。
做法:
用Map对地方进行影身,用Floyd求最短路。
刚刚发现map的key为string时,用char数组也是可以的。
注意大的数组最好开成全局变量,放在函数里容易挂掉。
代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <map>
#include <string>
#include <iostream>
using namespace std;
const int N=1005;
map<string,int> mat;
char city[N][N/2];
char s1[N/2],s2[N/2];
char c1,c2;
int f[N][N];
int min(int x,int y)
{
return x<y?x:y;
}
void work(int n,int c,int r)
{
int i,j,k,t,m,l,ans,cnt;
cnt=0;
mat.clear();
memset(f,0X3F,sizeof(f));
for(i=0;i<=c;i++)
{
scanf("%s",city[i]);
if(!mat[city[i]]) mat[city[i]]=++cnt;
}
for(i=1;i<=r;i++)
{
scanf("%s %c-%d-%c %s",s1,&c1,&l,&c2,s2);
if(!mat[s1]) mat[s1]=++cnt;
if(!mat[s2]) mat[s2]=++cnt;
k=mat[s1]; t=mat[s2];
if(c1=='<') f[t][k]=min(f[t][k],l);
if(c2=='>') f[k][t]=min(f[k][t],l);
}
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
ans=0;
k=mat[city[0]];
for(i=1;i<=c;i++)
{
ans+=f[k][mat[city[i]]]+f[mat[city[i]]][k];
}
printf("%d\n",ans);
}
int main()
{
int T,n,c,r;
T=0;
while(scanf("%d%d%d",&n,&c,&r),n||c||r)
{
printf("%d. ",++T);
work(n,c,r);
}
}