forked from stevenhalim/cpbook-code
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUVa10911.ml
58 lines (54 loc) · 1.41 KB
/
UVa10911.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
open Scanf
open Printf
let n = ref 0
let num_students = ref 0
let target = ref 0
let case = ref 1
let dist = Array.make_matrix 20 20 0.
let memo = Array.make (1 lsl 16) 0.
let hypot (ax, ay) (bx, by) =
Float.hypot (ax -. bx) (ay -. by)
;;
let rec matching bitmask =
if memo.(bitmask) > -0.5 then memo.(bitmask)
else if bitmask = !target then 0.
else begin
let ans = ref 1e9 in
let p1 = ref 0 in
while (bitmask land (1 lsl !p1) > 0) do
p1 := !p1 + 1
done;
for p2 = !p1 + 1 to !num_students - 1 do
if bitmask land (1 lsl p2) = 0 then
ans := min !ans (dist.(!p1).(p2) +. matching (bitmask lor (1 lsl !p1) lor (1 lsl p2)))
done;
!ans
end
let () =
let rec solve () =
scanf "%d" (fun x -> n := x);
if !n = 0
then
()
else begin
scanf "\n" ();
num_students := 2 * !n;
let positions = Array.make !num_students (0., 0.) in
for i = 0 to !num_students - 1 do
scanf "%s %f %f\n" (fun _ x y -> positions.(i) <- (x,y))
done;
for i = 0 to !num_students - 1 do
for j = i+1 to !num_students - 1 do
dist.(i).(j) <- hypot positions.(i) positions.(j)
done
done;
for i = 0 to (1 lsl 16) - 1 do
memo.(i) <- -1.
done;
target := (1 lsl !num_students) - 1;
printf "Case %d: %.2f\n" !case (matching 0);
case := !case + 1;
solve ()
end
in
solve ()