题目链接
题目大意:给你货币种类、交换点数量、最开始的货币种类和拥有的数量,问你有没有一种货币交换手段可以使货币越换越多。
最短路求负环的变形,最长路求正环。
const int maxn = 1e3+10;
struct point {
int u, v;
double r, c;
void add (int a, int b, double rr, double cc) {
u = a, v = b, r = rr, c = cc;
}
} e[maxn];
int n, m, s, tot; double v, d[maxn];
void bellman() {
for (int i = 1; i<=n; ++i) d[i] = 0; //全局数组默认为0,这句可以省略
d[s] = v; //以货币s开始,数量为v
bool update = true, ok = false; int cnt = 0;
while(update) {
update = false;
++cnt;
if (cnt > n) { //如果不存在正环那么最多松弛n轮
ok = true;
break;
}
for (int i = 0; i<tot; ++i)
if (d[e[i].v] < (d[e[i].u]-e[i].c)*e[i].r) {
update = true; //如果一轮中没有进行松弛那么就表明所有边都松弛完成了
d[e[i].v] = (d[e[i].u]-e[i].c)*e[i].r;
}
}
printf(ok ? "YES
" : "NO
");
}
int main(void) {
scanf("%d%d%d%lf", &n, &m, &s, &v);
for (int i = 0; i<m; ++i) {
int a, b; double r1, r2, c1, c2;
scanf("%d%d%lf%lf%lf%lf", &a, &b, &r1, &c1, &r2, &c2);
e[tot++].add(a, b, r1, c1);
e[tot++].add(b, a, r2, c2);
}
bellman();
return 0;
}