Arbitrage poj(贝尔曼福特判正权环+串)

53 阅读1分钟

Arbitrage

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 17691 Accepted: 7467

Description

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.

Output

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 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

\

\

\

套汇问题。。。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
    char  s[16];
    int num;
} qu[1000];
struct no//注意q[]的数组应该开大点,最环的情况为n*n
{
    int a,b;
    double r;
} q[1000];

char s1[16],s2[16];
double rate;
int   sum,n,m;
double  dis[1000000];

bool  bf()
{
    int i,j;
    memset(dis,0,sizeof(dis));
    dis[1]= 1  ;//一般题目没有名白的说从哪里开始,墨认为1
    for(i=1; i<n; i++)
        for(j=0; j<sum; j++)
            if(dis[q[j].b  ]<dis[ q[j].a  ]*q[j].r )
                dis[q[j].b   ]=dis[  q[j].a ]*q[j].r;
        for(j=0; j<sum; j++)//一定注意再判断正环时,只在q[]自己的范围内,而不是
            if(dis[q[j].b  ]<dis[ q[j].a  ]*q[j].r)
            {
                return   true ;
            }
    return false;
}
int cla=1;
int main()
{
    ios::sync_with_stdio(false);
    while(scanf("%d",&n)&&n)
    {
        sum=0;
        for(int i=1; i<=n; i++)
        {
            scanf("%s",qu[i].s);
            qu[i].num=i;
        }
        scanf("%d",&m);
        while(m--)
        {
            int a=0,b=0;
            scanf("%s%lf%s",s1,&rate,s2);
            for(int j=1; j<=n; j++)
            {
                if( ! strcmp(s1,qu[j].s)   )
                    a=qu[j].num;
                if(  !strcmp(s2,qu[j].s)   )
                    b=qu[j].num;
                if(a!=0&&b!=0)
                    break;
            }
            q[sum].a=a;
            q[sum].b=b;
            q[sum++].r=rate;
        }
        bool  o=bf();
        printf("Case %d: ",cla++);
        if(o==true)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

\

\

\

SPFA:

#include<map>
#include<queue>
#include<cmath>
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
char s[1000],s1[1000];
double Map[100][100],dis[100];

int m,n,tmp[100],sum;
bool vis[100];
bool spfa(){
    for(int i=0;i<=n;i++){
        dis[i]=0;
        vis[i]=false;
        tmp[i]=0;
    }

    dis[1]=1;
    vis[1]=true;
    queue<int>q;while(!q.empty())q.pop();
    q.push(1);
    while(!q.empty()){
        int u=q.front();q.pop();
        tmp[u]++;
        if(tmp[u]>n) return false;
        vis[u]=false;
        for(int i=1;i<=n;i++){
            if( (dis[i]<dis[u]*Map[u][i])&&Map[u][i]){
                dis[i]=dis[u]*Map[u][i];
                if(!vis[i]){
                    vis[i]=true;
                    q.push(i);
                }
            }
        }
    }
    return true;
}
int main(){
    int i,j,k,cnt=1;
    while(~scanf("%d",&n)&&n){
        sum=0;
        map<string,int>mp;
        mp.clear();
        for(i=1;i<=n;i++){
            scanf("%s",s);
            mp[s]=i;
        }
        for(i=0;i<100;i++){
            for(j=0;j<100;j++){
                Map[i][j]=0;
            }
        }
        scanf("%d",&m);
        double p;
        for(i=1;i<=m;i++){
            scanf("%s %lf %s",s,&p,s1);
            Map[mp[s]][mp[s1]]=p;
        }
        bool o=spfa();
        printf("Case %d: ",cnt++);
        if(!o){
            puts("Yes");
        }
        else
            puts("No");
    }
    return 0;
}


\