POJ 1860

2012.1.28

题外废话一下,我终于回来了,因为莫名的恐惧,竟然2个月没正经切题了。

  ——傲慢与懒惰是我目前的瓶颈。

POJ 1860

题目大意:sb有v个s币种,已知有若干种从a到b的兑换方式,以及所需的费用(现有100元a,兑换成b,汇率为10,手续费为10,则b=(a-手续费)*汇率)。问如果能通过某种顺序兑换来刷钱则输出yes,不能就输出no。

解:因为是针对最短路和最小生成树的练习,我感觉有点作弊的成分…

一开始想是否能找到一条s 到x的路,再x到s查看是否增加了,但感觉非常麻烦。后面想了想如果能成立则能无限刷钱,就是一个类似负环的问题,所以用了一个spfa+负环成立判定,把spfa的更新方式略改造就行了。

定义:dist为兑换到某币种的最大值。

更新见程序。

View Code
  1 const
2 maxn=100;
3 maxm=100;
4 type
5 data=record
6 dest, next: longint;
7 cost, cc: double;
8 end;
9 var
10 edge: array[1..(maxm shl 1)] of data;
11 vect: array[1..maxn]of longint;
12 dist: array[1..maxn]of double;
13 tot, n, m, s: longint;
14 v: double;
15 procedure add(x, y: longint; r, c: double);
16 begin
17 inc(tot);
18 with edge[tot] do
19 begin
20 dest := y;
21 cost := r;
22 cc := c;
23 next := vect[x];
24 vect[x] := tot;
25 end;
26 end;
27
28 procedure init;
29 var
30 i, j, x, y: longint;
31 z, o, p, q: double;
32 begin
33 tot := 0;
34 fillchar(dist, sizeof(dist), 0);
35 fillchar(vect, sizeof(vect), 0);
36 readln(n, m, s, v);
37 for i := 1 to m do
38 begin
39 readln(x, y, z, o, p, q);
40 add(x, y, z, o);
41 add(y, x, p, q);
42 end;
43 end;
44
45 function spfa(b, e: longint): boolean;
46 var
47 q, key: array[1..maxn]of longint;
48 visit: array[1..maxn]of boolean;
49 head, tail, i, u: longint;
50 tmp: double;
51 begin
52 fillchar(key, sizeof(key), 0);
53 fillchar(visit, sizeof(visit), 0);
54 head := 0;
55 tail := 1;
56 q[1] := b;
57 visit[b] := true;
58 dist[b] := v;
59 while head<>tail do
60 begin
61 head := head mod maxn +1;
62 u := q[head];
63 if key[u]>=n-1 then
64 begin
65 exit(true);
66 end;
67 inc(key[u]);
68 i := vect[u];
69 while i<>0 do
70 with edge[i] do
71 begin
72 tmp := (dist[u] - cc)*cost;
73 if tmp > dist[dest] then
74 begin
75 dist[dest] := tmp;
76 if not visit[dest] then
77 begin
78 visit[dest] := true;
79 tail := tail mod maxn +1;
80 q[tail] := dest;
81 end;
82 end;
83 i := next;
84 end;
85
86 visit[u] := false;
87 end;
88 exit(false);
89 end;
90
91 procedure print;
92 begin
93 if spfa(s, s) then writeln('YES')
94 else writeln('NO');
95 end;
96
97 begin
98 assign(input,'aaa.in'); reset(input);
99
100 init;
101 print;
102
103 close(input);
104 end.
原文地址:https://www.cnblogs.com/wmzisfoolish/p/2435142.html