题目意思其实就是要找一个正环,这里用到bellman-ford算法(其实什么算法无所谓,能找到那个环就可以),bellman-ford思想就是如果有v个定点,放缩v-1次,每次放缩用所有的边去更新其他节点,那么如果再更新发现还可以改变某些节点的权值,显然就是存在环(正环负环都一样)。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 220
int n, m, s;
int cnt;
double v;
struct Edge{
int a;
int b;
double r;
double c;
void set(int a, int b, double r, double c){
this->a = a;
this->b = b;
this->r = r;
this->c = c;
}
}edge[N];
double val[N];
bool Bellman_Ford(){
int i, j;
memset(val, 0, sizeof(val));
val[s] = v;
for(i = 1; i < n; i++){
for(j = 0; j < cnt ; j++){
int a = edge[j].a;
int b = edge[j].b;
double r = edge[j].r;
double c = edge[j].c;
val[b] = max( (val[a] - c) * r, val[b] );
}
}
for(i = 0; i < cnt; i++){
int a = edge[i].a;
int b = edge[i].b;
double r = edge[i].r;
double c = edge[i].c;
if( val[b] < ( val[a] -c ) * r) return true;
}
return false;
}
int main(){
int i,j;
while(scanf("%d %d %d %lf", &n, &m, &s ,&v)!=EOF){
cnt = 0;
for(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);
edge[cnt++].set(a, b, r1, c1);
edge[cnt++].set(b, a, r2, c2);
}
if(Bellman_Ford()){
printf("YES\n");
}else{
printf("NO\n");
}
}
return 0;
}