POJ 1860 Currency Exchange

POJ 1860 Currency Exchange

[★★☆☆☆]图论 最短路 Bellman

  • 题目大意:

    有多种汇币,汇币之间可以交换,这需要手续费,当你用100A币
    交换B币时,A到B的汇率是29.75,手续费是0.39,那么你可以得到
    (100 - 0.39) * 29.75 = 2963.3975 B币。问s币的金额经过交换最终
    得到的s币金额数能否增加。

  • 样例

    输入:
    3 2 1 20.0
    1 2 1.00 1.00 1.00 1.00
    2 3 1.10 1.00 1.10 1.00
    输出:
    YES

  • 解题思路:

    Bellman算法的变体,把寻找负环变为寻找正环就行了。
    我用的是强行循环找到mon[S] > V,辛亏题目比较友善,不然就超时了。
    推荐用循环有没有进行N次来判断有没有正环。这样在数据极端的情况下少了不少次的循环。

  • 代码

#include <iostream>
#include <algorithm>

using namespace std;

struct edge {
    int from, to;
    double R, C; // rate, cost
};

int N, M, S;
double V;
edge E[205];
int cte;
double mon[105]; //money

bool Bellman()
{
    while(1) {
        bool update = false;
        for (int i = 0; i < cte; i++) {
            edge e = E[i];
            if (mon[e.from] > 0 && mon[e.to] < (mon[e.from]-e.C)*e.R) {
                mon[e.to] = (mon[e.from]-e.C)*e.R;
                update = true;
            }
        }
        if (!update) break;
        if (mon[S] > V) break;
    }

    if (mon[S] > V) return true;
    return false;
}


int main() {
    cte = 0;
    cin >> N >> M >> S >> V;

    for (int i = 1; i <= N; i++) {
        mon[i] = 0;
    }
    mon[S] = V;

    for (int i = 0; i < M; i++) {
        edge te;
        cin >> te.from >> te.to >> te.R >> te.C;
        E[cte++] = te;
        cin >> te.R >> te.C;
        int t = te.from; te.from = te.to; te.to = t;
        E[cte++] = te;
    }


    if (Bellman()) cout << "YES\n";
    else cout << "NO\n";

    return 0;
}




你可能感兴趣的:(poj)