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;
}

posted @ 2010-04-28 22:39  北海小龙  阅读(197)  评论(0编辑  收藏  举报