题意:从初始点到多个点的来回最短路径总和。
这题输入的时候比较麻烦,注意用map容器存储各点。注意一个目标点可能出现多次。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#define N 110
#define INF 0x7ffffff
#define M 1100
using namespace std;
int n,t,v[N],d[N],a[N][N],b[M];
int spfa(int s)
{
for(int i=1;i<=n;i++) d[i]=INF,v[i]=0;
queue<int> q;
q.push(1);
v[1]=1;
d[1]=0;
while(!q.empty())
{
int c=q.front();
q.pop();
v[c]=0;
for(int i=1;i<=n;i++)
{
if(s&&d[i]>d[c]+a[c][i])
{
d[i]=d[c]+a[c][i];
if(!v[i]) v[i]=1,q.push(i);
}
if(!s&&d[i]>d[c]+a[i][c])
{
d[i]=d[c]+a[i][c];
if(!v[i]) v[i]=1,q.push(i);
}
}
}
int ans=0;
for(int i=2;i<=t+1;i++) ans+=d[b[i]];
return ans;
}
int main()
{
int kase=0,m;
while(~scanf("%d%d%d",&n,&t,&m)&&(n||t||m))
{
map<string,int> mp;
int cnt=0;
for(int i=1;i<=t+1;i++)
{
char name[20];
scanf("%s",name);
if(mp[name]==0) mp[name]=++cnt;
b[i]=mp[name];
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=INF;
for(int i=0;i<m;i++)
{
char n1[20],s[20],n2[20];
scanf("%s%s%s",n1,s,n2);
if(mp[n1]==0) mp[n1]=++cnt;
if(mp[n2]==0) mp[n2]=++cnt;
int len=strlen(s),num=0;
for(int j=0;j<len;j++)
if(s[j]>='0'&&s[j]<='9')
num=num*10+s[j]-'0';
if(s[0]=='<')
a[mp[n2]][mp[n1]]=min(a[mp[n2]][mp[n1]],num);
if(s[len-1]=='>')
a[mp[n1]][mp[n2]]=min(a[mp[n1]][mp[n2]],num);
}
printf("%d. %d\n",++kase,spfa(0)+spfa(1));
}
}