题意:

给出一些货币和货币之间的兑换比率,问是否可以使某种货币经过一些列兑换之后,货币值增加。

举例说就是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)的更多相关文章

  1. poj 2240 Arbitrage(Bellman_ford变形)

    题目链接:http://poj.org/problem?id=2240 题目就是要通过还钱涨自己的本钱最后还能换回到自己原来的钱种. 就是判一下有没有负环那么就直接用bellman_ford来判断有没 ...

  2. POJ 2240 Arbitrage(Floyed-Warshall算法)

    题意:给出n种货币,m种兑换比率(一种货币兑换为另一种货币的比率),判断测试用例中套汇是否可行.(套汇的意思就是在经过一系列的货币兑换之后,是否可以获利.例如:货币i→货币j→货币i,这样兑换后,是否 ...

  3. POJ 2240 Arbitrage(SPFA+邻接矩阵)

    ( ̄▽ ̄)" #include<iostream> #include<cstdio> #include<cmath> #include<algori ...

  4. poj 2240 Arbitrage (Floyd)

    链接:poj 2240 题意:首先给出N中货币,然后给出了这N种货币之间的兑换的兑换率. 如 USDollar 0.5 BritishPound 表示 :1 USDollar兑换成0.5 Britis ...

  5. POJ 3259 Wormholes (Bellman_ford算法)

    题目链接:http://poj.org/problem?id=3259 Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submis ...

  6. POJ 2240 Arbitrage(floyd)

    http://poj.org/problem?id=2240 题意 : 好吧,又是一个换钱的题:套利是利用货币汇率的差异进行的货币转换,例如用1美元购买0.5英镑,1英镑可以购买10法郎,一法郎可以购 ...

  7. POJ 2240 Arbitrage(判正环)

    http://poj.org/problem?id=2240 题意:货币兑换,判断最否是否能获利. 思路:又是货币兑换题,Belloman-ford和floyd算法都可以的. #include< ...

  8. POJ 2240 Arbitrage (求负环)

    Arbitrage 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/I Description Arbitrage is the ...

  9. POJ 2240 Arbitrage (Bellman Ford判正环)

    Arbitrage Time Limit: 1000MS   Memory Limit: 65536K Total Submissions:27167   Accepted: 11440 Descri ...

随机推荐

  1. 更好的逐帧动画函数 — requestAnimationFrame 简介

    本文将会简单讲讲 requestAnimationFrame 函数的用法,与 setTimeout/setInterval 的区别和联系,以及当标签页隐藏时 requestAnimationFrame ...

  2. 完整的社交app源码android+laravel

    等想到写点什么的时候再写吧,其他看代码. https://github.com/huijimuhe/monolog-android https://github.com/huijimuhe/monol ...

  3. PHP 实现页面静态化

    PHP文件执行阶段:语法分析->编译->运行 静态html文件执行顺序:运行 动态程序: 连接数据库服务器或者缓存服务器->获取数据->填充到模板->呈现给用户 关于优化 ...

  4. 网页样式——各种炫酷效果持续更新ing...

    1.evanyou效果-彩带的实现,效果如下 注:这个主要用的是Canvas画布实现的,点击背景绘制新的图形,代码如下: /*Html代码:*/ <canvas id=">< ...

  5. SSH框架 sequence diagram

  6. webpack入坑之旅(一)不是开始的开始

    最近学习框架,选择了vue,然后接触到了vue中的单文件组件,官方推荐使用 Webpack + vue-loader构建这些单文件 Vue 组件,于是就开始了webpack的入坑之旅.因为原来没有用过 ...

  7. Day Six(Beta)

    站立式会议 站立式会议内容总结 331 今天:完成闹钟功能,远程数据库采用bmob的解决方案,应用初始化bmob 遇到问题:闹钟没有取消提醒 以及多次设置提醒的问题 明天:修改闹钟问题,完成文件下载( ...

  8. openwrt刷机后配置PPPOE上网方法

    参考下帖13#的方式: 如何编辑配置openwrt,来实现pppoe拨号上网? 但其中有一句代码有错误: option 'peerdns' '0',其中需将‘0’改为‘1’

  9. Mustache 使用总结

    前言: 在分析 jeesite 项目的时候,看到了 Mustache,于是查了下 正文: 1.Mustache 概述 Mustache 是基于 JavaScript 实现的模板引擎,即用来 渲染前台页 ...

  10. js 打开窗口window.open

    js改变原有的地址 window.open(webPath+'/index?code='+code,'_self');