POJ 1860题
//Bellman-Ford算法的变形,关键理解松弛操作
#include <stdio.h>
#include <string.h> //引入memset的头文件
#define arraysize 1001
#define nodesize 101
//将每种货币兑换后的价值作为结点
typedef struct node
{
int u; //要兑换的货币
int v; //目的货币
double r; //兑换率
double c; //佣金
}node;
node edges[arraysize];
double d[nodesize];
int n,m,s;
int esize; //边的个数
double v; //此处使用double
bool bellman()
{
memset(d,0,sizeof(d)); //由于松弛操作是向大的方向进行,所以此处赋值为0
d[s] = v;
while(d[s]<=v)
{
bool final = true; //循环终止的条件,当所有的边无法进行松弛时
for(int i=1;i<esize+1;i++) //对所有边进行松弛操作
{
if(d[edges[i].v]<(d[edges[i].u]-edges[i].c)*edges[i].r) //松弛操作与Bellman-Ford算法不同,此处是往大的方向松弛
{
d[edges[i].v] = (d[edges[i].u]-edges[i].c)*edges[i].r;
final = false;
}
}
if(final)
{
break;
}
}
return (d[s]>v);
}
int main()
{
//freopen("1.txt","r",stdin);
while(scanf("%d%d%d%lf",&n,&m,&s,&v)!=EOF) //读取double类型使用lf
{
int a,b;
double rab,cab,rba,cba;
esize = 0;
for(int i=0;i<m;++i)
{
esize++;
scanf("%d%d%lf%lf%lf%lf",&a,&b,&rab,&cab,&rba,&cba);
//生成了两条边
edges[esize].u = a;
edges[esize].v = b;
edges[esize].r = rab;
edges[esize].c = cab;
esize++;
edges[esize].u = b;
edges[esize].v = a;
edges[esize].r = rba;
edges[esize].c = cba;
}
if(bellman())
printf("YES\n");
else
printf("NO\n");
}
return 0;
}