题目大意
有多种汇币,汇币之间可以交换,这需要手续费,当你用100A币交换B币时,A到B的汇率是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.