POJ 2240 Arbitrage【Bellman_ford坑】

連接:



Arbitrage
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 13067   Accepted: 5493

Descriptionios

Arbitrage is the use of discrepancies in currency exchange rates to transform one unit of a currency into more than one unit of the same currency. For example, suppose that 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. Then, by converting currencies, a clever trader can start with 1 US dollar and buy 0.5 * 10.0 * 0.21 = 1.05 US dollars, making a profit of 5 percent. 

Your job is to write a program that takes a list of currency exchange rates as input and then determines whether arbitrage is possible or not. 

Input算法

The input will contain one or more test cases. Om the first line of each test case there is an integer n (1<=n<=30), representing the number of different currencies. The next n lines each contain the name of one currency. Within a name no spaces will appear. The next line contains one integer m, representing the length of the table to follow. The last m lines each contain the name ci of a source currency, a real number rij which represents the exchange rate from ci to cj and a name cj of the destination currency. Exchanges which do not appear in the table are impossible. 
Test cases are separated from each other by a blank line. Input is terminated by a value of zero (0) for n.

Outputapp

For each test case, print one line telling whether arbitrage is possible or not in the format "Case case: Yes" respectively "Case case: No".

Sample Inputspa

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 Outputcode

Case 1: Yes
Case 2: No

Sourceorm




題意:


      判斷是否存在使得匯率增多的環
    【任意一個點的匯率增多均可以】

算法:bellman_ford 判斷「正環」


注意:

          這裏的鬆弛操做要循環 N 次才能過,
       書上的鬆弛操做一直都是 N-1 次
       對於爲何是 N 或者 N-1 次一直沒有理解清楚


code:

2240 Accepted 224K 110MS C++ 1781B

/*******************************************************
題意:判斷是否存在使得匯率增多的環
      【任意一個點的匯率增多均可以】
算法:bellman_ford 判斷正環
注意:這裏的鬆弛操做要循環 N 次才能過,
       書上的鬆弛操做一直都是 N-1 次
       對於爲何是 N 或者 N-1 次一直沒有理解清楚
********************************************************/
#include<stdio.h>
#include<string.h>
#include<string>
#include<map>
#include<algorithm>
#include<iostream>
using namespace std;

const int maxn = 40;
double d[maxn];
int n,m;

struct Edge{
    int u,v;
    double r;
}edge[maxn*maxn];
map<string, int> mp;

bool bellman_ford(int s)
{
    memset(d,0,sizeof(d));
    d[s] = 1;
    for(int i = 1; i <= n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            int u = edge[j].u;
            int v = edge[j].v;
            double r = edge[j].r;
            if(d[v] < d[u]*r)
                d[v] = d[u]*r;
        }
    }
    if(d[s] > 1.0) return true;
    else return false;
}

int main()
{
    int kcase = 0;
    while(scanf("%d", &n) != EOF)
    {
        if(n == 0) break;
        mp.clear();

        string s;
        for(int i = 1; i <= n; i++)
        {
            cin>>s;
            mp[s] = i;
        }

        scanf("%d", &m);
        string s1,s2;
        double rat;
        for(int i = 0; i < m; i++)
        {
            cin>>s1>>rat>>s2;
            edge[i].u = mp[s1];
            edge[i].v = mp[s2];
            edge[i].r = rat;
        }

        bool flag = false;
        for(int i = 1; i <= n; i++)
        {
            if(bellman_ford(i))
            {
                flag = true;
                break;
            }
        }
        printf("Case %d: ", ++kcase);
        if(flag) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}




仍是用 floyd 簡單方便了Orz

 /*******************************************************
題意:判斷是否存在使得匯率增多的環
      【任意一個點的匯率增多均可以】
算法:floyd 簡單變形
    w[i][j] = max(w[i][j], w[i][k]*w[k][j])

********************************************************/
#include<stdio.h>
#include<string.h>
#include<string>
#include<map>
#include<algorithm>
#include<iostream>
using namespace std;

const int maxn = 40;
double d[maxn];
int n,m;

double w[maxn][maxn];
map<string, int> mp;

void floyd()
{
    for(int k = 1; k <= n; k++)
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                w[i][j] = max(w[i][j], w[i][k]*w[k][j]);
}

int main()
{
    int kcase = 0;
    while(scanf("%d", &n) != EOF)
    {
        if(n == 0) break;
        mp.clear();

        string s;
        for(int i = 1; i <= n; i++)
        {
            cin>>s;
            mp[s] = i;
            w[i][i] = 1; //本身到本身的匯率爲 1, 注意這個初始化必須寫在下面建圖前面。。。
        }

        scanf("%d", &m);
        string s1,s2;
        double rat;
        for(int i = 0; i < m; i++)
        {
            cin>>s1>>rat>>s2;
            w[mp[s1]][mp[s2]] = rat;
        }

        floyd();

        int flag = 0;
        for(int i = 1; i <= n; i++)
        {
            if(w[i][i] > 1.0)
            {
                flag = 1; break;
            }
        }
        printf("Case %d: ", ++kcase);
        if(flag) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}
相關文章
相關標籤/搜索