POJ 1860 Currency Exchange

SPFA判断是否存在最长路,只要存在负权环就存在最长路,两者是等价的。

将N中货币看成N个点,从A点到B的最大可能值为 

(A点的当前值 - AB的手续费) * AB的汇率。

/*Accepted    428K    16MS    C++    1452B    2012-07-27 10:21:22*/

#include<cstdio>

#include<cstdlib>

#include<cstring>

#include<queue>

#include<algorithm>

#define cal(i, j) ( (val[i] - c[i][j]) * r[i][j])

using namespace std;

const int MAXN = 1 << 7;

int n, m, s;

double v, r[MAXN][MAXN], c[MAXN][MAXN];



struct Node

{

    int x;

    double value;

};



void ReadGraph()

{

    memset( r, 0, sizeof r);

    while( m --)

    {

        int a, b;

        scanf( "%d%d", &a, &b);

        scanf( "%lf%lf%lf%lf", &r[a][b], &c[a][b], &r[b][a], &c[b][a]);

    }

}



bool Spfa()

{

    queue<Node> q;

    Node u, y;

    int cnt[MAXN] = {0};

    double val[MAXN] = {0.0};

    u.x = s, u.value = v;

    val[s] = v, ++ cnt[s];

    q.push(u);

    while( !q.empty())

    {

        u = q.front(), q.pop();

        while( u.value < val[u.x])

        {

            u = q.front(), q.pop();

        }

        if( cnt[u.x] > n) return true; //存在负权环

        for( int i = 1; i <= n; i ++)

        {

            if( r[u.x][i] && cal(u.x, i) > val[i])

            {

                val[i] = cal( u.x, i);

                y.x = i, y.value = val[i];

                q.push(y);

                ++ cnt[i];

            }

        }

    }

    return false;

}



int main()

{

    while( scanf( "%d%d%d%lf", &n, &m, &s, &v) != EOF)

    {

        ReadGraph();

        bool ok = Spfa();

        if(ok)

            printf( "YES\n");

        else

            printf( "NO\n");

    }

    return 0;

}

 

 

你可能感兴趣的:(Exchange)