POJ - 1860 Currency Exchange (spfa判负环)

POJ - 1860 题目链接

思路

一开始写到这个章节的时候不会写这道题,原因就是不知道spfa到底有什么用,因为一直听说spfa已死,这句话。
这是一道典型的spfa找负环的题,但是这里不同的是,这了的"负环"其实是正环。
稍加处理一下链式向前星,加入一个cost消耗量,接下来就是裸的spfa判断负环板子了

代码

Powered by CK 2020:04:08
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int N = 1e3 + 10;
int head[N], to[N], nex[N], cnt;
double rate[N], cost[N], dis[N], beg;
int visit[N], num[N], n, m, rt;
void add(int x, int y, double r, double c) {
    to[cnt] = y;
    nex[cnt] = head[x];
    rate[cnt] = r;
    cost[cnt] = c;
    head[x] = cnt++;
}
bool spfa() {
    memset(dis, 0, sizeof dis);
    memset(visit, 0, sizeof visit);
    memset(num, 0, sizeof num);
    queue<int> q;
    q.push(rt);
    dis[rt] = beg;
    visit[rt] = 1;
    num[rt] = 1;
    while(!q.empty()) {
        int temp = q.front();
        q.pop();
        visit[temp] = 0;
        for(int i = head[temp]; i; i = nex[i]) {
            if(dis[to[i]] < (dis[temp] - cost[i]) * rate[i]) {
                dis[to[i]] = (dis[temp] - cost[i]) * rate[i];
                if(++num[to[i]] == n)   return true;
                if(!visit[to[i]]) {
                    visit[to[i]] = 1;
                    q.push(to[i]);
                }
            }
        }
    }
    return dis[rt] > beg;
}
int main() {
    // freopen("in.txt", "r", stdin);
    int x, y;
    double r, c;
    while(scanf("%d %d %d %lf", &n, &m, &rt, & beg) != EOF) {
        cnt = 1;
        memset(head, 0, sizeof head);
        for(int i = 0; i < m; i++) {
            scanf("%d %d %lf %lf", &x, &y, &r, & c);
            add(x, y, r, c);
            scanf("%lf %lf", &r, &c);
            add(y, x, r, c);
        }
        if(spfa())  puts("YES");
        else    puts("NO");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lifehappy/p/12663357.html