[题目来源]:POJ2240
[关键字]:判断环
[题目大意]:给出一些汇率,问是否能将手中的钱通过兑换,使最后再换回本币时数量增加。
//=====================================================================================================
[分析]:就是判断给出的图中是否存在一条正权环。但是要注意的是,因为路径权值不再是单纯相加,而是有了乘法就不能保证n-1次松弛后就能判断环,可以将结束条件改为:1、不能再松弛(无环)。2、源点已增大(有环)。
[代码]:
View Code
1 program Project1;
2 type
3 rec = record
4 x, y: longint;
5 d: real;
6 end;
7 var
8 n, m, tc: longint;
9 w: array[0..100] of string;
10 d: array[0..200] of real;
11 e: array[0..2000] of rec;
12
13 function findname(s: string):longint;
14 var
15 i: longint;
16 begin
17 for i := 1 to n do
18 if w[i] = s then exit(i);
19 end;
20
21 procedure make(i, x, y: longint; d: real);
22 begin
23 e[i].x := x;
24 e[i].y := y;
25 e[i].d := d;
26 end;
27
28 procedure init;
29 var
30 i, x, y: longint;
31 d: real;
32 s: string;
33 ch: char;
34 begin
35 for i := 1 to n do
36 readln(w[i]);
37 readln(m);
38 for i := 1 to m do
39 begin
40 read(ch);
41 s := '';
42 while ch <> ' ' do
43 begin
44 s := s+ch;
45 read(ch);
46 end;
47 x := findname(s);
48 read(d);
49 read(ch);
50 readln(s);
51 y := findname(s);
52 make(i,x,y,d);
53 end;
54 readln;
55 //for i := 1 to m do writeln(e[i].x,' ',e[i]. y,' ',e[i].d);
56 end;
57
58 function bellman(st: longint):boolean;
59 var
60 i: longint;
61 f: boolean;
62 begin
63 for i := 1 to n do d[i] := -maxlongint;
64 d[st] := 1;
65 while 1 = 1 do
66 begin
67 f := true;
68 for i := 1 to m do
69 if d[e[i].y] < d[e[i].x]*e[i].d then
70 begin
71 d[e[i].y] := d[e[i].x]*e[i].d;
72 f := false;
73 end;
74 if d[st] > 1 then exit(true);
75 if f then exit(false);
76 end;
77 end;
78
79 procedure work;
80 var
81 i: longint;
82 begin
83 for i := 1 to n do
84 if bellman(i) then
85 begin
86 writeln('Case ',tc,': Yes');
87 exit;
88 end;
89 writeln('Case ',tc,': No');
90 end;
91
92 begin
93 readln(n);
94 tc := 0;
95 while n <> 0 do
96 begin
97 inc(tc);
98 init;
99 work;
100 readln(n);
101 end;
102 end.