POJ 1860 Currency Exchange

来源:互联网 发布:centos 安装中文包 编辑:程序博客网 时间:2024/06/16 11:19

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]; //moneybool 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;}
0 0