您的位置:首页 > 其它

POJ 1860 Currency Exchange bellman_ford

2012-08-08 17:06 309 查看
题意:

有N个货币兑换所,每个兑换所兑换2种货币A和B。分别有汇率RAB,RBA,和回扣CAB,CBA;

问是否可以通过货币之间的转化而盈利。

思路:

一开始以为是dijk求单源点距离然后判断最后的距离是否大于初始值,后来发现做不出来。

看了discuss才发现用的是bellman_ford算法。好久没用了,都生疏了,就先去把以前的题看了一下,POJ3259。

只不过3259求的是是否存在负环,是bellman_ford的标准作法。

这题有点变形,求的是是否存在一个环使得两点之间的值可以无限递增。

只需要在最后判断环的步骤上改变一下即可

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#include <iomanip>
#define PI acos(-1.0)
#define Max 2005
#define inf 1<<28
using namespace std;

int n,m,s;
double money;
struct kdq
{
int u,v;
double huilv;
double cost;
} currency[Max];//货币
double dis[Max];
void bellman_ford(int num)
{
int i,j;
for(i=1; i<=n; i++)
dis[i]=-inf;//因为求的是最大值,所以初始化的时候要dis[]--> -∞;
dis[s]=money;
bool flag=0;
for(i=1; i<=n; i++)
{
for(j=1; j<=num; j++)
{
if(dis[currency[j].u]!=-inf&&dis[currency[j].v]<(dis[currency[j].u]-currency[j].cost)*currency[j].huilv)//松弛
{
dis[currency[j].v]=(dis[currency[j].u]-currency[j].cost)*currency[j].huilv;
}
}
}
for(j=1; j<=num; j++)//判断是否形成无限增大的环
{
double temp=(dis[currency[j].u]-currency[j].cost)*currency[j].huilv;
if(dis[currency[j].v]!=-inf&&dis[currency[j].v]<temp)//如果dis[v]<temp,则证明该环可以无限增加,所以可以盈利
{
flag=1;
break;
}
}
if(flag)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
int main()
{
int i,j,k,l,a,b;
double Rab,Cab,Rba,Cba;
cin>>n>>m>>s>>money;
int num=0;
for(i=1; i<=m; i++)
{
num++;
cin>>a>>b>>Rab>>Cab>>Rba>>Cba;
currency[i].u=a,currency[i].v=b;
currency[i].huilv=Rab,currency[i].cost=Cab;
num++;
currency[i+m].u=b,currency[i+m].v=a;
currency[i+m].huilv=Rba,currency[i+m].cost=Cba;
}
bellman_ford(2*m);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  exchange 算法