我的 第一道图论题...
如果真的能这么换就爽了,就是钱能在不同的国家之间相互兑换,有兑换公式y=(x-c)*r,y是兑换后的钱,x是兑换前的钱,注意钱的单位是不一样的,并且钱在两国之间的兑换比例并无关系,是有向图
现在就是给你一定量的钱和指定的国家,问你能否再进行兑换之后,使钱的价值升高...
其实就是找一个正环,钱在这个正环里循环可以无限增多,或者某条路径可以使起始点的价值升高.
bellman-Ford算法可以判是否有负环,可以利于这个性质,更改松弛的条件,巧妙的判断是否有正环
#include <cstdio>
#include <string.h>
#define eps 1e-8
using namespace std;
struct E{
double r,c;
int x,y;
}e[204];
double d[102],v;
int s,t;
int bellman(){
int sign;
memset(d,0,sizeof(d));
d[s]=v;
while(d[s]<=v+eps){//当起点升值就没有必要再循环了
sign=1;
for(int i=0;i<t;i++){//松弛操作,标志
if(d[e[i].y]+eps<(d[e[i].x]-e[i].c)*e[i].r){
sign=0;
d[e[i].y]=(d[e[i].x]-e[i].c)*e[i].r;
}
}
if(sign){//没有点能够进行松弛操作了,根据起始点的开始态和终态决定返回值
return d[s]-v;
}
}
return 1;
}
int main(){
int n,m;
while(scanf("%d%d%d%lf",&n,&m,&s,&v)!=EOF){
t=0;
for(int i=0;i<m;i++){//输入边的信息,每行数据两条边,是有向图
scanf("%d%d%lf%lf%lf%lf",&e[t].x,&e[t].y,&e[t].r,&e[t].c,&e[t+1].r,&e[t+1].c);
e[t+1].x=e[t].y,e[t+1].y=e[t].x;
t+=2;
}
printf(bellman()?"YES\n":"NO\n");
}
return 0;
}