//这两天做的最短路,基本上都和字符串扯上关系了,都要用map容器,尤其是这题,写起代码来有点耗时间,
//而且要注意的细节特别多,只要多刷刷这样的题目,下次看到这样的题目,就不会那么
//害怕了,知道一步一步来,用map来解决问题!
//这题还有就是一个地方有多辆破车,那么就是一辆一辆来拉
//
//
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <cctype>
#include <string>
using namespace std;
const int maxn=1005;
const int inf=0x3f3f3f3f;
int mp[maxn][maxn];
int p[maxn];
char q[maxn];
int n,c,r;
void init()
{
int i,j;
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
{
if(i==j)mp[i][j]=0;
else
mp[i][j]=inf;
}
}
}
void floyd()
{
int k,i,j;
for(k=1; k<=n; k++)
{
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
{
if(mp[i][j]>mp[i][k]+mp[k][j]&&mp[i][k]!=inf&&mp[k][j]!=inf)//这里要注意判断条件
mp[i][j]=mp[i][k]+mp[k][j];
}
}
}
}
int main()
{
map<string,int>m;
string s1,s2;
string s3,s4,s5;
int d,k;
int tcase=0;
while(scanf("%d%d%d",&n,&c,&r),n+c+r)
{
init();
m.clear();
cin>>s1;
k=1;
m[s1]=k++;//第一个修车厂要单独拿出来处理
for(int i=1; i<=c; i++)
{
cin>>s2;
if(!m[s2])
m[s2]=k++;
p[i]=m[s2];//用数组来记录废弃的车,用map映射的标号,同时记录破车的数量
}
for(int j=1; j<=r; j++)
{
cin>>s3>>s4>>s5;
if(!m[s3])
m[s3]=k++;
if(!m[s5])
m[s5]=k++;
int flag[2]= {0,0};//这里很关键,用来下面判断方向
int b=0;
for(int i=0; i<s4.size(); )
{
if(s4[i]=='>')flag[0]=1;
if(s4[i]=='<')flag[1]=1;
while(isdigit(s4[i]))//这里用到了isdigit()函数,用来判断是不是数字
{
q[b]=s4[i];//用一个数组来存这些数字,但还是字符串
b++;
i++;
}
q[b]='\0';//这里容易错,就是用来最后一个结束
i++;
}
sscanf(q,"%d",&d);//sscanf将字符串转化为int型数字
if(flag[0]&&mp[m[s3]][m[s5]]>d)mp[m[s3]][m[s5]]=d;//这里就是用来判断方向,是单向还是双向,只要两个IF就够了,
if(flag[1]&&mp[m[s5]][m[s3]]>d)mp[m[s5]][m[s3]]=d;//自己想想就知道了,这使我想起线段树另一个模板也是只要两个if就够了
}
floyd();
int sum=0;
for(int i=1; i<=c; i++)
{
sum+=mp[1][p[i]]+mp[p[i]][1];//这里注意去了,还要拉回来!!
}
printf("%d. %d\n",++tcase,sum);
}
return 0;
}
HDU 2923
最新推荐文章于 2019-06-07 19:26:36 发布