HDU 2923

//这两天做的最短路,基本上都和字符串扯上关系了,都要用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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值