POJ - 1860 - Currency Exchange(bellman-ford 判负环)

题目链接
题目大意:给你货币种类、交换点数量、最开始的货币种类和拥有的数量,问你有没有一种货币交换手段可以使货币越换越多。
  最短路求负环的变形,最长路求正环。

const int maxn = 1e3+10;
struct point {
    int u, v;
    double r, c;
    void add (int a, int b, double rr, double cc) {
        u = a, v = b, r = rr, c = cc;
    }
} e[maxn];
int n, m, s, tot; double v, d[maxn];
void bellman() {
    for (int i = 1; i<=n; ++i) d[i] = 0; //全局数组默认为0,这句可以省略
    d[s] = v; //以货币s开始,数量为v
    bool update = true, ok = false; int cnt = 0;
    while(update) {
        update = false; 
        ++cnt;
        if (cnt > n) { //如果不存在正环那么最多松弛n轮
            ok = true;
            break;
        }
        for (int i = 0; i<tot; ++i)
            if (d[e[i].v] < (d[e[i].u]-e[i].c)*e[i].r) {
                update = true; //如果一轮中没有进行松弛那么就表明所有边都松弛完成了
                d[e[i].v] = (d[e[i].u]-e[i].c)*e[i].r;
            }
    }
    printf(ok ? "YES\n" : "NO\n");
}
int main(void) {
    scanf("%d%d%d%lf", &n, &m, &s, &v);
    for (int i = 0; i<m; ++i) {
        int a, b; double r1, r2, c1, c2;
        scanf("%d%d%lf%lf%lf%lf", &a, &b, &r1, &c1, &r2, &c2);
        e[tot++].add(a, b, r1, c1);
        e[tot++].add(b, a, r2, c2);
    }
    bellman();
    return 0;
}
posted @ 2020-03-31 15:40  shuitiangong  阅读(101)  评论(0编辑  收藏  举报