IT民工
加油!

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;
}

 

 

posted on 2012-07-27 10:33  找回失去的  阅读(217)  评论(0编辑  收藏  举报