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