POJ 2240 Arbitrage (求负环)
Arbitrage
题目链接:
http://acm.hust.edu.cn/vjudge/contest/122685#problem/I
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
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
Hint
##题意:
求货币经过一系列兑换操作后能否升值.
##题解:
转化为图模型后就是求满足条件的环是否存在.
这里把求最短路时的加法改成乘法即可,结果就是是否存在环使得路径大于1.
以下分别用三种方法求:
bellman-ford和floyd用时都较多,800+ms.
spfa只需要90+ms, 不过需要用c++交,否则TLE.(真是神奇)
##代码:
####spaf法:94ms (必须用c++交,否则TLE)
``` cpp
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
#define eps 1e-8
#define maxn 1100
#define inf 0x3f3f3f3f
#define IN freopen("in.txt","r",stdin);
using namespace std;
int m,n,k;
int edges, u[maxn], v[maxn];
double w[maxn];
int first[maxn], _next[maxn];
double dis[maxn];
void add_edge(int s, int t, double val) {
u[edges] = s; v[edges] = t; w[edges] = val;
_next[edges] = first[s];
first[s] = edges++;
}
queue q;
bool inq[maxn];
int inq_cnt[maxn];
bool spfa(int s) {
memset(inq, 0, sizeof(inq));
memset(inq_cnt, 0, sizeof(inq_cnt));
for(int i=1; i<=n; i++) dis[i] = 0; dis[s] = 1;
while(!q.empty()) q.pop();
q.push(s); inq_cnt[s]++;
while(!q.empty()) {
int p = q.front(); q.pop();
inq[p] = 0;
for(int e=first[p]; e!=-1; e=_next[e]) {
double tmp = dis[u[e]] * w[e];
if(dis[v[e]] < tmp) {
dis[v[e]] = tmp;
if(!inq[v[e]]) {
q.push(v[e]);
inq[v[e]] = 1;
inq_cnt[v[e]]++;
if(inq_cnt[v[e]] >= n) return 0;
}
}
}
}
return 1;
}
map<string,int> name;
int main(int argc, char const *argv[])
{
//IN;
int ca = 1;
while(scanf("%d", &n) != EOF && n)
{
memset(first, -1, sizeof(first));
edges = 0;
name.clear();
for(int i=1; i<=n; i++) {
string s; cin >> s;
name.insert(make_pair(s, i));
}
cin >> m;
for(int i=1; i<=m; i++) {
string s,t; double w;
cin>> s >> w >> t;
int u = name.find(s)->second;
int v = name.find(t)->second;
add_edge(u,v,w);
}
if(!spfa(1)) printf("Case %d: Yes\n", ca++);
else printf("Case %d: No\n", ca++);
}
return 0;
}
####bellman-ford法:875ms
``` cpp
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#define LL long long
#define eps 1e-8
#define maxn 1100
#define inf 0x3f3f3f3f
#define IN freopen("in.txt","r",stdin);
using namespace std;
int m,n,k;
int edges, u[maxn], v[maxn];
double w[maxn];
int first[maxn], next[maxn];
double dis[maxn];
void add_edge(int s, int t, double val) {
u[edges] = s; v[edges] = t; w[edges] = val;
next[edges] = first[s];
first[s] = edges++;
}
bool bellman(int s) {
for(int i=1; i<=n; i++) dis[i]=0; dis[s] = 1;
for(int i=1; i<=n; i++) {
for(int e=0; e<edges; e++) {
double tmp = dis[u[e]] * w[e];
if(dis[v[e]] < tmp) {
dis[v[e]] = dis[u[e]] * w[e];
if(i == n) return 0;
}
}
}
return 1;
}
map<string,int> name;
int main(int argc, char const *argv[])
{
//IN;
int ca = 1;
while(scanf("%d", &n) != EOF && n)
{
memset(first, -1, sizeof(first));
edges = 0;
name.clear();
for(int i=1; i<=n; i++) {
string s; cin >> s;
name.insert(make_pair(s, i));
}
cin >> m;
for(int i=1; i<=m; i++) {
string s,t; double w;
cin>> s >> w >> t;
int u = name.find(s)->second;
int v = name.find(t)->second;
add_edge(u,v,w);
}
if(!bellman(1)) printf("Case %d: Yes\n", ca++);
else printf("Case %d: No\n", ca++);
}
return 0;
}
floyd法:875ms
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#define LL long long
#define eps 1e-8
#define maxn 35
#define inf 0x3f3f3f3f
#define IN freopen("in.txt","r",stdin);
using namespace std;
int m,n,k;
double dis[maxn][maxn];
void floyd() {
for(int k=1; k<=n; k++)
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
if(dis[i][j] < dis[i][k]*dis[k][j])
dis[i][j] = dis[i][k] * dis[k][j];
}
map<string,int> name;
int main(int argc, char const *argv[])
{
//IN;
int ca = 1;
while(scanf("%d", &n) != EOF && n)
{
name.clear();
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
dis[i][j] = (i==j? 1.0:inf);
for(int i=1; i<=n; i++) {
string s; cin >> s;
name.insert(make_pair(s, i));
}
cin >> m;
for(int i=1; i<=m; i++) {
string s,t; double w;
cin>> s >> w >> t;
int u = name.find(s)->second;
int v = name.find(t)->second;
dis[u][v] = w;
}
floyd();
int flag = 1;
for(int i=1; i<=n; i++)
if(dis[i][i] > 1.0) {flag = 0;break;}
if(!flag) printf("Case %d: Yes\n", ca++);
else printf("Case %d: No\n", ca++);
}
return 0;
}
POJ 2240 Arbitrage (求负环)的更多相关文章
- POJ 2240 Arbitrage (spfa判环)
Arbitrage Arbitrage is the use of discrepancies in currency exchange rates to transform one unit of ...
- POJ 2240 Arbitrage / ZOJ 1092 Arbitrage / HDU 1217 Arbitrage / SPOJ Arbitrage(图论,环)
POJ 2240 Arbitrage / ZOJ 1092 Arbitrage / HDU 1217 Arbitrage / SPOJ Arbitrage(图论,环) Description Arbi ...
- POJ 3259 Wormholes(最短路径,求负环)
POJ 3259 Wormholes(最短路径,求负环) Description While exploring his many farms, Farmer John has discovered ...
- 最短路(Floyd_Warshall) POJ 2240 Arbitrage
题目传送门 /* 最短路:Floyd模板题 只要把+改为*就ok了,热闹后判断d[i][i]是否大于1 文件输入的ONLINE_JUDGE少写了个_,WA了N遍:) */ #include <c ...
- bzoj 1486: [HNOI2009]最小圈 dfs求负环
1486: [HNOI2009]最小圈 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1022 Solved: 487[Submit][Status] ...
- Contest20140710 loop bellman-ford求负环&&0/1分数规划
loop|loop.in|loop.out 题目描述: 给出一个有向带权图,权为边权,求一个简单回路,使其平均边权最小. 简单回路指不多次经过同一个点的回路. 输入格式: 第一行两个整数,表示图的点数 ...
- poj 2240 Arbitrage 题解
Arbitrage Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 21300 Accepted: 9079 Descri ...
- POJ3259 Wormholes —— spfa求负环
题目链接:http://poj.org/problem?id=3259 Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submis ...
- poj 2240 Arbitrage(Bellman_ford变形)
题目链接:http://poj.org/problem?id=2240 题目就是要通过还钱涨自己的本钱最后还能换回到自己原来的钱种. 就是判一下有没有负环那么就直接用bellman_ford来判断有没 ...
- ACM: POJ 3259 Wormholes - SPFA负环判定
POJ 3259 Wormholes Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu ...
随机推荐
- $.post()
定义和用法 post() 方法通过 HTTP POST 请求从服务器载入数据. jQuery.post(url,data,success(data, textStatus, jqXHR),dataTy ...
- java6 新特新
JAVA6新特性介绍 1. 使用JAXB来实现对象与XML之间的映射 JAXB是Java Architecture for XML Binding的缩写,可以将一个Java对象转变成为XML格式, ...
- UVa 11542 (高斯消元 异或方程组) Square
书上分析的太清楚,我都懒得写题解了.=_=|| #include <cstdio> #include <cstring> #include <cmath> #inc ...
- UVa 10375 (唯一分解定理) Choose and divide
题意: 求组合数C(p, q) / C(r, s)结果保留5为小数. 分析: 先用筛法求出10000以内的质数,然后计算每个素数对应的指数,最后再根据指数计算答案. #include <cstd ...
- Java Web编程的主要组件技术——JDBC
参考书籍:<J2EE开源编程精要15讲> JDBC(Java DataBase Connectivity)是Java Web应用程序开发的最主要API之一.当向数据库查询数据时,Java应 ...
- android调用JPush获取手机的注册码(Cordova环境)
JPushInterface.addLocalNotification(cordova.getActivity().getApplication().getApplicationContext(), ...
- LeetCode Contains Duplicate (判断重复元素)
题意: 如果所给序列的元素不是唯一的,则返回true,否则false. 思路: 哈希map解决. class Solution { public: bool containsDuplicate(vec ...
- MYSQL自动备份策略的选择
目前流行几种备份方式: 1.逻辑备份:使用mysql自带的mysqldump工具进行备份.备份成sql文件形式.优点:最大好处是能够与正在运行的mysql自动协同工作,在运行期间可以确保备份是当时的点 ...
- [FIX BUG]获取theme中自定义textColor时报的错误
我在Fragment中inflate它都可以,可是一旦使用ListView来inflate就会报错,说找不到我自定义的attr!研究了半天发现是我的inflate的context有问题: view = ...
- 硬盘结构介绍--mbr及分区
硬盘刚买来使用时需要经过分区然后格式化才能够使用,硬盘经过分区后,分区软件便会写一个主引导扇区,这个扇区位于硬盘的 0 磁道 0 柱面第1扇区(即0区)(注意:该扇区为隐含扇区,0道0面的全部扇区均为 ...