Currency Exchange POJ - 1860 负权环检测变形

题意:

在一个城市中有 n 个货币交换点,每个交换点可以接受两种货币的交换,不同的交换方式有不同的汇率和手续费。问是否存在一种交换方式使得某人在这个交换过程中可以获利。

思路:

这道题不难,本题类似于负权环的检测,经过负权环之后,成本可以不断减少。如果我们在这道题中存在一个环可以使得我们不断获利,那么我们必然可以在整个过程中获利。我们在 Bellman-Ford 算法或者 SPFA 算法中对收入进行松弛。套用前面两个算法中的负权环检测方法即可求出。

代码:

#include <vector>
#include <iostream>
#include <cstdio>
#define N 105
#define fp(p,q,r) for(int p = q;p < r;p++)
typedef long long ll;
typedef double dl;
using namespace std;
ll n,m,s;
dl v,d[N];
struct edge{
    ll from,to;
    double rab,cab;
    edge(ll a,ll b,dl c,dl d):from(a),to(b),rab(c),cab(d){};
};
vector <edge> edges;
bool bf(){
    fill(d,d+N,0);
    d[s]=v;
    fp(i,0,n){
//      bool f=0;
        fp(j,0,2*m){
            edge e=edges[j];
            if(d[e.to]<(d[e.from]-e.cab)*e.rab){
                d[e.to]=(d[e.from]-e.cab)*e.rab;
                if(i==n-1) return true;//如果进行了 n - 1 次松弛,那么必存在“负权环”
//              f=1;
            }
        }
//      if(!f) break;
    }
//  fp(i,0,m*2){
//      edge e=edges[i];
//      if(d[e.to]<(d[e.from]-e.cab)*e.rab) return true;
//  }
    return false;
}
int main(void)
{
    cin >> n >> m >> s >> v;
    fp(i,0,2 * m){
        ll a,b;dl c,d,e,f;
        cin >> a >> b >> c >> d >> e >> f;
        edges.push_back(edge(a,b,c,d));
        edges.push_back(edge(b,a,e,f));
    }
    cout << (bf() ? "YES" : "NO") << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值