POJ 2240 - Arbitrage(bellman_ford & floyd)
题意:
给出一些货币和货币之间的兑换比率,问是否可以使某种货币经过一些列兑换之后,货币值增加。
举例说就是1美元经过一些兑换之后,超过1美元。可以输出Yes,否则输出No。
分析:
首先我们要把货币之间的关系转化成一张图。转化时,用STL里面的map很方便。
为每种货币分配一个序列号,一个序列号代表了一个图中间的NODE,而node之间的edge用汇率表示。
一开始用Dijkstra算法做,死活AC不了,网友给的理由是:
由于Dijkstra算法不能处理带有负权值的最短路,但此题中,两种货币之间的兑换比率可能小于1,相当于这条路径的权值为负
前车之鉴,WA的代码:
#include<iostream>
#include<cstdio>
#include<queue>
#include<string.h>
#include<string>
#include<map>
using namespace std;
#define maxn 31
#define inf 0x3f3f3f3f
double edges[maxn][maxn];
double dist[maxn];
typedef pair<int,int> P;
void init(){
for(int i=1;i<maxn;i++)
for(int j=1;j<maxn;j++)
edges[i][j]=(i==j?1:0);//1代表等价价换,0:代表无法交换
} void dijkstra(int s,int n){
bool visited[maxn];
memset(visited,0,sizeof(visited));
visited[s]=true;
for(int i=1;i<=n;i++)
dist[i]=edges[s][i];
for(int i=1,u;i<=n;i++){
double max=-1;
for(int j=1;j<=n;j++)
if(!visited[j]&&dist[j]>max){
max=dist[j]; u=j;
} visited[u]=true;
for(int j=1;j<=n;j++){
if(dist[u]*edges[u][j]>dist[j])
dist[j]=dist[u]*edges[u][j];
}
}
} int main(){
//freopen("in.txt","r",stdin);
int n,cases=0;
while(scanf("%d",&n)!=EOF && n){
cases++;
init();
map<string,int> ma;
string s,t;
for(int i=1;i<=n;i++){
cin>>s;
ma.insert(make_pair(s,i));
}
int m;
double tmp;
scanf("%d",&m);
while(m--){
cin>>s>>tmp>>t;
edges[ma[s]][ma[t]]=tmp;
} dijkstra(1,n);
printf("Case %d: ",cases);
if(dist[1]>1.0)
printf("Yes\n");
else
printf("No\n");
}
}
最后写了一个Floyd的代码版本,结果一下子就过了,我只能默默的哭了
#include<iostream>
#include<cstdio>
#include<queue>
#include<string.h>
#include<string>
#include<map>
using namespace std;
#define maxn 31
#define inf 0x3f3f3f3f
double edges[maxn][maxn];
void init(){
for(int i=1;i<maxn;i++)
for(int j=1;j<maxn;j++)
edges[i][j]=(i==j?1:0);//1:代表等价交换,0:代表无法交换
} void floyd_warshall(int s,int n){
for(int k=1;k<=n;k++){
for(int i=1,u;i<=n;i++){
for(int j=1;j<=n;j++){
if(edges[i][k]*edges[k][j]>edges[i][j])//如果找到了更好的交换方案
edges[i][j]=edges[i][k]*edges[k][j];
}
}
}
} int main(){
//freopen("in.txt","r",stdin);
int n,cases=0;
while(scanf("%d",&n)!=EOF && n){
cases++;
init();
map<string,int> ma;
string s,t;
for(int i=1;i<=n;i++){
cin>>s;
ma.insert(make_pair(s,i));
}
int m;
double tmp;
scanf("%d",&m);
while(m--){
cin>>s>>tmp>>t;
edges[ma[s]][ma[t]]=tmp;
} dijkstra(1,n);
printf("Case %d: ",cases);
/*for(int i=1,u;i<=n;i++){
for(int j=1;j<=n;j++){
printf("%.2f ",edges[i][j]);
}
printf("\n");
}*/
if(edges[1][1]>1.0)
printf("Yes\n");
else
printf("No\n");
}
}
最后再用bellman_ford模板成功ac了一次。
#include<iostream>
#include<cstdio>
#include<queue>
#include<string.h>
#include<string>
#include<map>
using namespace std; #define maxn 1000
#define inf 0x3f3f3f3f
struct edge{
int from;
int to;
float cost;
edge(){
from=0,to=0,cost=0;
}
edge(int a,int b ,float c){
from=a,to=b,cost=c;
}
};
edge Edges[maxn];
float dist[maxn];
void bellman_ford(int s,int V,int E){
for(int i=1;i<=V;i++)
dist[i]=0;
dist[s]=1.0;
for(int i=1;i<=V;i++){//这里可以改成while(true),但在有负权的情况下,会增加更多的循环,故建议照样例中写
bool update=false;
for(int j=1;j<=E;j++){
edge e=Edges[j];
if(dist[e.to]<dist[e.from]*e.cost){
dist[e.to]=dist[e.from]*e.cost;
update=true;
}
}
if(!update)break;//一旦在某次循环中,不能再更新当前dist,那么就能提前结束该算法,break之
}
} void init(int n){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j) Edges[i]=edge(i,j,1.0);//初始化,1:等价交换
else Edges[i]=edge(i,j,0); //0:无法交换
}
}
} int main(){
//freopen("in.txt","r",stdin);
int n,cases=0;
while(scanf("%d",&n)!=EOF && n){
cases++;
init(n);
map<string,int> ma;
string s,t;
for(int i=1;i<=n;i++){
cin>>s;
ma.insert(make_pair(s,i)); //构造字符串与数值的映射关系
}
int m;
double tmp;
scanf("%d",&m);
for(int i=1;i<=m;i++){
cin>>s>>tmp>>t;
Edges[i]=edge(ma[s],ma[t],tmp);
} bellman_ford(1,n,m);
printf("Case %d: ",cases);
if(dist[1]>1.0)
printf("Yes\n");
else
printf("No\n");
}
}
【问题】:Folyd算法能处理包含负权边的图吗?
答案是可以的。Floyd-Warshall算法和Bellman-Ford算法一样,可以处理边是负数的情况。
---《挑战程序设计竞赛》 P.103
POJ 2240 - Arbitrage(bellman_ford & floyd)的更多相关文章
- poj 2240 Arbitrage(Bellman_ford变形)
题目链接:http://poj.org/problem?id=2240 题目就是要通过还钱涨自己的本钱最后还能换回到自己原来的钱种. 就是判一下有没有负环那么就直接用bellman_ford来判断有没 ...
- POJ 2240 Arbitrage(Floyed-Warshall算法)
题意:给出n种货币,m种兑换比率(一种货币兑换为另一种货币的比率),判断测试用例中套汇是否可行.(套汇的意思就是在经过一系列的货币兑换之后,是否可以获利.例如:货币i→货币j→货币i,这样兑换后,是否 ...
- POJ 2240 Arbitrage(SPFA+邻接矩阵)
( ̄▽ ̄)" #include<iostream> #include<cstdio> #include<cmath> #include<algori ...
- poj 2240 Arbitrage (Floyd)
链接:poj 2240 题意:首先给出N中货币,然后给出了这N种货币之间的兑换的兑换率. 如 USDollar 0.5 BritishPound 表示 :1 USDollar兑换成0.5 Britis ...
- POJ 3259 Wormholes (Bellman_ford算法)
题目链接:http://poj.org/problem?id=3259 Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submis ...
- POJ 2240 Arbitrage(floyd)
http://poj.org/problem?id=2240 题意 : 好吧,又是一个换钱的题:套利是利用货币汇率的差异进行的货币转换,例如用1美元购买0.5英镑,1英镑可以购买10法郎,一法郎可以购 ...
- POJ 2240 Arbitrage(判正环)
http://poj.org/problem?id=2240 题意:货币兑换,判断最否是否能获利. 思路:又是货币兑换题,Belloman-ford和floyd算法都可以的. #include< ...
- POJ 2240 Arbitrage (求负环)
Arbitrage 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/I Description Arbitrage is the ...
- POJ 2240 Arbitrage (Bellman Ford判正环)
Arbitrage Time Limit: 1000MS Memory Limit: 65536K Total Submissions:27167 Accepted: 11440 Descri ...
随机推荐
- 每一个C#开发者必须知道的13件事情
1.开发流程 程序的Bug与瑕疵往往出现于开发流程当中.只要对工具善加利用,就有助于在你发布程序之前便将问题发现,或避开这些问题. 标准化代码书写 标准化代码书写可以使代码更加易于维护,尤其是在代码由 ...
- BASH 命令以及使用方法小结
最近工作中需要写一个Linux脚本,用到了很多BASH命令,为了防止以后忘记,在这里把它们一一记下来.可能会比较乱,随便看看就好了.如果有说的不对的地方也欢迎大家指正. 1,export VAR=.. ...
- ASP.NET 系列:单元测试之StructureMap
ASP.NET使用StructureMap等依赖注入组件时最重要就是EntityFramework的DbContext对象要保证在每次HttpRequest只有一个DbContext实例,这里将使用第 ...
- 自己存档:asp.net mvc 从filterContent得到controller和action
//filterContext.RouteData.GetRequiredString("controller") + "/" + filterContext. ...
- 37-more 简明笔记
分页显示文本 more [options] file more用于分页显示文本文件,最早出现在BSD当中,但这一命令非常基本,后来less命令对其做了增强,所谓的less也就是少即是多 参数 file ...
- linux 下第一个cordova android app
上篇博客写了linux下 cordova + ionic 环境的搭建 , 今天就来做下第一个app的简单讲解吧 首先昨天已经可以通过命令行的方式创建app了.经过今天好一段时间的研究发现使用 ioni ...
- extJs学习基础2
一个登陆界面: Ext.onReady(function(){ Ext.define('Login', { //renderTo: Ext.getBody(), extend: 'Ext.window ...
- zabbix 用 LLD 完全自动化监控 Oracle
文章转载自:http://mp.weixin.qq.com/s?__biz=MzA3MzYwNjQ3NA==&mid=2651296856&idx=1&sn=2bdf78071 ...
- iOS开发小技巧--即时通讯项目:使用富文本在UILabel中显示图片和文字;使用富文本占位显示图片
Label借助富文本显示图片 1.即时通讯项目中语音消息UI的实现,样式如图: 借助富文本在UILabel中显示图片和文字 // 1.创建一个可变的富文本 NSMutableAttributedStr ...
- CMY/CMYK 打印机色彩
CMY 发光物体和反光物体产生颜色的机制不同. 前者指光源光, 它的颜色由发光波长决定. 后者指不能发光但却能表现出颜色的物体, 例如色素. 色素的颜色由它不能吸收的光的波长决定. 比如红色色素, 除 ...