前天wa了数次的一道题,整理一下。
/*
zoj_1544 最短路
一开始一直想着floyd。。写到一半才发现无从下手。。
改用bellman的话似乎很简单,判断存在 正边权环 就行了。对模板稍微做了改变。
没有控制精度wa了无数次,至于为什么要控制精度。引用某acmer的一句话:
double精度在15-16位,大小在1.7E-308~1.7E+308,如果esp == 1e-15,则比较的
结果不准呢。这个应该是造成TLE的问题吧。可能一直比较,得不到要的结果。。。
所以我觉得,不控制精度的话某些数据可能导致它一直比较下去,直到突破1e-15,
导致比较错误。。
所以以后遇到实数的大小比较问题一定要考虑到精度控制问题,不然极易导致TLE
*/
#include <iostream>
#include <limits.h>
#include <cstdio>
#define eps 1e-8
using namespace std;
struct currency
{
double rate,commi;
int sta,end;
void set( int a,int b,double i,double j )
{
sta=a,end=b;
rate=i,commi=j;
}
};
currency map[300];
double dist[110];
void bellman( int n,int s,double v,int edge )
{
int i,j,a,b;
double temp;
bool in;
for( i=0;i<=n;i++ )
dist[i]=0; //因为钱数非负所以初始设置为0
dist[s]=v;
for( i=1;i<=n;i++ )
{
in=false;
for( j=0;j<edge;j++ )
{
a=map[j].sta , b=map[j].end;
temp=( dist[a]-map[j].commi )*map[j].rate;
if( dist[b]+eps < temp )
{
dist[b]=temp;
in=true;
}
}
if( !in ) break;
}
if( i==n+1 ) printf("YES\n");
else printf("NO\n");
}
int main()
{
int i,j,n,m,s;
int a,b;
double v,t1,t2,t3,t4;
while( scanf("%d%d%d%lf",&n,&m,&s,&v)!=EOF )
{
j=0;
for( i=0;i<m;i++ )
{
scanf( "%d%d%lf%lf%lf%lf",&a,&b,&t1,&t2,&t3,&t4 );
map[j++].set( a,b,t1,t2 );
map[j++].set( b,a,t3,t4 );
}
bellman( n,s,v,j );
}
return 0;
}