用到的是 Bellman-Ford 算法。有些不同的是标准的 Bellman-Ford 是求最短路径的,而这道题有求最大路径的意思。需要判断的是是否有回路,这里也跟标准的判断是否有负权回路有所不同,这里判断的是是否有“正权回路”。
具体实现方法是,只要将原本算法中的大于号小于号全部反转即可。交的时候自己心里也没底,后来竟然一次过了~
#include<iostream>
#include<algorithm>
#define FOR(i, N) for(int i = 1; i <= (N); i++)
using namespace std;
typedef struct{
int from, to;
float cms, rate;
} EDGE;
EDGE ex[700];
void read(int N, int M){
int t = 0;
FOR(i, 600)
ex[i].from = ex[i].to = 0;
FOR(i, M){
int x, y;
cin >> x >> y;
ex[t].from = ex[t+1].to = x;
ex[t].to = ex[t+1].from = y;
cin >> ex[t].rate >> ex[t].cms;
cin >> ex[t+1].rate >> ex[t+1].cms;
t += 2;
}
}
bool bellmanFord(int N, int S, float V){
float d[400];
FOR(i, N)
d[i] = 0;
d[S] = V;
FOR(i, N - 1){
int t = 0;
while(ex[t].from != 0){
d[ex[t].to] = max(d[ex[t].to], (d[ex[t].from] - ex[t].cms) * ex[t].rate);
t++;
}
}
FOR(i, N - 1){
int t = 0;
while(ex[t].from != 0){
if(d[ex[t].to] < (d[ex[t].from] - ex[t].cms) * ex[t].rate)
return false;
t++;
}
}
return true;
}
int main(){
int N, M, S;
float V;
cin >> N >> M >> S >> V;
read(N, M);
if(! bellmanFord(N, S, V))
cout << "YES" << endl;
else
cout << "NO" << endl;
}