POJ 1860 Currency Exchange bellman_ford

来源:互联网 发布:剑指offer java版pdf 编辑:程序博客网 时间:2024/05/16 03:22

题意:

有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<<28using 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;}


原创粉丝点击