题意:求根据各种货币之间的汇率能否使某种货币升值。货币a兑换成b所得值是 (a-c[a][b])*r[a][b]。
思路:令dist[a]表示从s(最初所持货币)出发经过各种已知的汇率兑换成a所能得到的最大值。那么便可以发现一个明显的放缩条件:(dist[a]-c[a][b])*r[a][b]>dist[b]。如此便可以用bellman水了。另外需要注意的是不仅是存在正权回路的时候需要输出YES,当图中不存在正权回路,但通过求最长路后dist[s]>v时同样需要输出YES
/*
Sample Input
3 2 1 20.0
1 2 1.00 1.00 1.00 1.00
2 3 1.10 1.00 1.10 1.00
Sample Output
YES
*/
#include<cstdio>
#include<cstring>
#define MAXVN 120
#define MAXEN 2200
#define INF 100000000
using namespace std;
typedef struct{
int u, v;
double value, c;
}Edge;
Edge eg[MAXEN];
double dis[MAXVN];
int vn, en;
int Bellman_Ford(int st, double v){
for(int i = 1; i <= vn; i++){
dis[i] = 0;
}
//printf("eg1v:%d\v", eg[1].v);
dis[st] = v;
bool realxed = 0;
for(int i = 1; i <= vn - 1; i++){
for(int j = 1; j <= en; j++){
if(dis[eg[j].v] < (dis[eg[j].u] - eg[j].c)*eg[j].value){
dis[eg[j].v] = (dis[eg[j].u] - eg[j].c)*eg[j].value;
realxed = 1;
}
//printf("dfsf");
}
if(!realxed) break;
}
for(int j = 1; j <= en; j++){
if(dis[eg[j].v] < (dis[eg[j].u] - eg[j].c)*eg[j].value) return 1;
}
return 0;
}
int main(){
int n, m, s,a, b;
double v, rab, cab,rba, cba;
while(scanf("%d%d%d%lf", &n, &m, &s, &v) != EOF){
vn = n;en = 2*m;
int count = 1;
//printf("n:%d m:%d s:%d v:%lf\n", n, m, s, v);
while(m--){
scanf("%d%d%lf%lf%lf%lf",&a, &b, &rab, &cab, &rba, &cba);
//printf("eg1v:%d\n", b);
eg[count].u = a;
eg[count].v = b;
eg[count].value = rab;
eg[count++].c = cab;
eg[count].u = b;
eg[count].v = a;
eg[count].value = rba;
eg[count++].c = cba;
}
if(Bellman_Ford(s,v) == 1) printf("YES\n");
else printf("NO\n");
}
}