hdu 1217 Arbitrage (floyd+map)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1217

题意:一种货币可以根据汇率兑换成其他货币,问是否可以通过兑换来获利例如 1 US Dollar buys 0.5 British pound, 1 British pound buys 10.0 French francs, and 1

 French franc buys 0.21 US dollar.那么1 US dollar and buy 0.5 * 10.0 * 0.21 = 1.05 US dollars;就可以把1美元换成1.05美元;

如果可以获利输出Case case: Yes否则Case case: No;


思考:一共有n种货币,对于每一种货币我们可以把它对应到一个整数i上;我们可以用c++的map来处理;



map<string,int> M;
string s,t;
for (int i=1;i<=n;i++)
{     
    cin>>s;     
    M[s]=i;
}
for (int i=0;i<m;i++)
{
     cin>>s>>val>>t;
     f[M[s]][M[t]] = val;
}

</pre><pre>
 

我们可以先认为对于每一种货币 i 对于本身的汇率是1;考虑是否可以通过某一种货币 k 使得 从 i 兑换成 k ,然后再通过 k 兑换成 i;使得汇率增加;我们可以想到用floyd;只不过不是求最短路,而是求最大汇率;

<pre name="code" class="cpp">for (int k=1;k<=n;k++)
{
     for (int i=1;i<=n;i++)
     {
          for (int j=1;j<=n;j++)
          {
              if (f[i][j] < f[i][k]*f[k][j])
                  f[i][j] = f[i][k]*f[k][j];
          }
      }
}

 

对于初始化的问题要放在数据处理的开头;

我们要把f[i][i]赋值为1;这个要在读数据前完成,因为数据中有这样的情况:1 US Dollar buys 2 US Dollars;一开始我就是把数据初始化放在了读入的后面,忽略了这种情况难过

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
using namespace std;
double f[50][50];
map<string,int> M;
int main()
{
    int n,m,flag,cnt=1;
    double val;
    string s,t;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0) break;
        memset(f,0,sizeof(f));
        for(int i=1;i<=n;i++) f[i][i]=1.0;
        M.clear();
        flag=0;
        for(int i=1;i<=n;i++)
        {
            cin>>s;
            M[s]=i;
        }
        scanf("%d",&m);
        for(int i=0;i<m;i++)
        {
            cin>>s>>val>>t;
            f[M[s]][M[t]]=val;
        }
        for(int k=1;k<=n;k++)
        {
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(f[i][j] < f[i][k]*f[k][j])
                        f[i][j] = f[i][k]*f[k][j];
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(f[i][i]>1.0)
            {
                flag=1;
                break;
            }
        }
        if(flag==1)  printf("Case %d: Yes\n",cnt++);
        else printf("Case %d: No\n",cnt++);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值