poj 1860 Currency Exchange bellman

题目大意

  有多种汇币,汇币之间可以交换,这需要手续费,当你用100A币交换B币时,AB的汇率是29.75,手续费是0.39,那么你可以得到(100 - 0.39) * 29.75 = 2963.3975 B币。问s币的金额经过交换最终得到的s币金额数能否增加,因为货币的交换是可以重复多次的,所以我们需要找出是否存在正权回路。

分析

  就是要求有没有正环,用bellman求最长路,经过n次松弛后如果还可以松弛,那就有正环,输出YES。

注意

  要把每种汇币当做点,把交换当做边,权值为一个函数:(现在有的钱-手续费)*汇率

代码

  

const
 maxe=10000;
 maxv=20000;

type
 arr=record
   x,y:longint;
   w,t:real;
 end;

var
 n,m,f:longint;
 s:real;
 a:array[1..maxv] of arr;
 d:array[1..maxe] of real;
 i,j,k:longint;
  
procedure relax(u,v:longint;w,t:real);
var
  i:real;
begin
  i:=(d[u]-t)*w;
  if i>d[v] then
    d[v]:=i;
end;

function bellman:boolean;
var
  i,j:integer;
  k:real;
begin
  for i:=1 to n do
    for j:=1 to m do
      with a[j] do relax(x,y,w,t);
  for i:=1 to m do
    with a[i] do
      begin
        k:=(d[x]-t)*w;
        if k>d[y] then exit(true);
      end;
  exit(false)
end;

begin
      readln(n,m,f,s);
      fillchar(a,sizeof(a),0);
      fillchar(d,sizeof(d),0);
      for j:=1 to m do
        begin
          with a[j*2-1] do
            read(x,y,w,t);
          a[j*2].x:=a[j*2-1].y;
          a[j*2].y:=a[j*2-1].x;
          with a[j*2] do
            read(w,t);
        end;
      m:=m*2;
      d[f]:=s;
      if bellman
        then writeln('YES')  
        else writeln('NO');
end.

posted @ 2016-04-15 19:43  一个响亮的蒟蒻  阅读(115)  评论(0编辑  收藏  举报