POJ 2240 && HDU 1217 Arbitrage(Floyd)

Description
给定一些货币之间的单向汇率,问一笔钱能否经过若干次对换而增值
Input
多组用例,每组用例第一行为货币种数n,之后n行为货币类型,第n+2行为兑换规则数m,之后m行为货币之间的单向汇率,每组用例后跟一空行,以n=0结束输入
Output
对于每组用例,若是一笔钱能够经过若干次兑换后增值则输出Yes,否则输出No
Sample Input
3
USDollar
BritishPound
FrenchFranc
3
USDollar 0.5 BritishPound
BritishPound 10.0 FrenchFranc
FrenchFranc 0.21 USDollar

3
USDollar
BritishPound
FrenchFranc
6
USDollar 0.5 BritishPound
USDollar 4.9 FrenchFranc
BritishPound 10.0 FrenchFranc
BritishPound 1.99 USDollar
FrenchFranc 0.09 BritishPound
FrenchFranc 0.19 USDollar

0
Sample Output
Case 1: Yes
Case 2: No
Solution
根据输入建立有向图,不能使用dijaskra,因为增值的方法不一定是优先选择最小的路径,并不是贪心所能解决的,所以要用以动态规划为基本思想的floyd来做,建完图后跑一边floyd判断是否存在g[i][i]>1的情况出现即可
Code

#include <stdio.h>
#include <string.h>
#define maxn 40
double g[maxn][maxn];
int n;
char hash[maxn][40];
int position(char str[])//货币名称不好记录,用数字代替字符串来代表货币 
{
    int pos;
    for(pos=1;;pos++)
        if(!strcmp(hash[pos],str))
            return pos;
}
void flody()
{
    int i,j,k;
    for(k=1;k<=n;k++)
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                if(g[i][j]<g[i][k]*g[k][j])
                    g[i][j]=g[i][k]*g[k][j];
}
int main()
{
    char s[40],t[40];
    double c;
    int times=1,flag,i,m;
    while(scanf("%d",&n)!=EOF&&n)
    {
        for(i=1;i<=n;i++)
            scanf("%s",hash[i]);
        memset(g,0,sizeof(g));//初始化 
        scanf("%d",&m);
        while(m--)//输入路径,注意路是单向路 
        {
            scanf("%s %lf %s",s,&c,t);
            g[position(s)][position(t)]=c;
        }
        flody();
        flag=0;
        for(i=1;i<=n;i++)//存在正环,满足条件 
            if(g[i][i]>1.0)
            {
                flag=1;
                break;
            }
        if(flag)
            printf("Case %d: Yes\n",times++);
        else
            printf("Case %d: No\n",times++);
        getchar();
    }
    return 0;
}

你可能感兴趣的:(POJ 2240 && HDU 1217 Arbitrage(Floyd))