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 ...
随机推荐
- linux/shell sort命令
sort是在Linux里常用的一个命令,用来排序的 # man sort 1 sort的工作原理 sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最 ...
- 函数fsp_try_extend_data_file
扩展表空间 /***********************************************************************//** Tries to extend t ...
- uva580Critical Mass
递推. 用f[i]代表i个盒子的放法,设g[i]=2^n-f[i],代表i个盒子不满足条件的放法. 枚举第一个U所在的位置j.则方法有g[j-2]*(2^(i-j-2))种,j-1必须是L. 所以 ...
- bzoj1412: [ZJOI2009]狼和羊的故事
空地之间开始没有连然后一直WA...题意混乱...尴尬. #include<cstdio> #include<cstring> #include<iostream> ...
- I.MX6 开机 闪红屏
/************************************************************************** * I.MX6 开机 闪红屏 * 说明: * 本 ...
- apache开源项目 -- tez
为了更高效地运行存在依赖关系的作业(比如Pig和Hive产生的MapReduce作业),减少磁盘和网络IO,Hortonworks开发了DAG计 算框架Tez.Tez是从MapReduce计算框架演化 ...
- crtmpserver流媒体服务器的介绍与搭建
crtmpserver流媒体服务器的介绍与搭建 (2012-02-29 11:28) 标签: crtmpserver C++ RTMP Server rtmp Adobe FMS(Flash ...
- 数据库语言(二):SQL语法实例整理
连接表达式: select * from student join takes on student.ID = takes.ID; 通过on后面的谓词作为连接条件,相同的属性可以出现两次,也就是等价于 ...
- ZOJ3865:Superbot(BFS) The 15th Zhejiang University Programming Contest
一个有几个小坑的bfs 题目很长,但并不复杂,大概总结起来有这么点. 有t组输入 每组输入n, m, p.表示一个n*m的地图,每p秒按键会右移一次(这个等会儿再讲). 然后是地图的输入.其中'@'为 ...
- Binary Tree Level Order Traversal java实现
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, ...