Arbitrage
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 29374 | Accepted: 12279 |
题目链接:http://poj.org/problem?id=2240
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
题意:
给出几种货币单位,以及货币与货币之间的兑换汇率,问最后是否能够套利。就是用1个单位的货币,不断去兑换其它的货币,最后得到大于1个单位的相应货币。
题解:
总的思路就是跑最长路看看是否有正环吧,有的话就说明至少存在一种货币可以用来套利。
这里跑最长路的时候要把之前的“ + ”改造为“ * ”,至于正确性,乘法取个对数也等价于加吧?具体证明我也不是很清楚。
代码如下:
#include <cstdio> #include <algorithm> #include <cstring> #include <iostream> #include <queue> #include <cmath> #include <map> #include <string> #include <stack> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; const int N = 35; map <string,int> mp; int n,num; struct Edge{ int u,v,next; double w; }e[N*N<<1]; int head[N],vis[N],c[N]; int tot; void adde(int u,int v,double w){ e[tot].v=v;e[tot].w=w;e[tot].next=head[u];head[u]=tot++; } double d[N]; int spfa(int s){ memset(d,0,sizeof(d));memset(vis,0,sizeof(vis)); d[s]=1;queue <int> q;q.push(s);memset(c,sizeof(c)); c[s]=1;vis[s]=1; while(!q.empty()){ int u=q.front();q.pop();vis[u]=0; for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].v; if(d[v]<d[u]*e[i].w){ d[v]=d[u]*e[i].w; if(!vis[v]){ vis[v]=1; q.push(v); if(++c[v]>n) return 1; } } } } return 0; } int main(){ int cnt =0; while(scanf("%d",&n)!=EOF){ if(n==0) break ; string s; num=0;cnt++; for(int i=1;i<=n;i++){ cin>>s; mp[s]=++num; } int tmp; scanf("%d",&tmp); memset(head,-1,sizeof(head));tot=0; for(int i=1;i<=tmp;i++){ string s1,s2; double w; cin>>s1>>w>>s2; adde(mp[s1],mp[s2],w); } printf("Case %d: ",cnt); if(spfa(1)) puts("Yes"); else puts("No"); } return 0; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。