-
Notifications
You must be signed in to change notification settings - Fork 1
/
SHOPTRIP.java
137 lines (113 loc) · 3.72 KB
/
SHOPTRIP.java
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import java.awt.*;
import java.io.*;
import java.util.StringTokenizer;
public class SHOPTRIP {
public static void main(String[] args) {
InputReader input = new InputReader(System.in);
PrintWriter output = new PrintWriter(System.out);
Problem SHOPTRIP = new Problem();
SHOPTRIP.Solve(input, output);
output.close();
}
static class Problem {
int n, k;
Point[] pos;
int[] shops;
double[][] dp;
int full;
double dist (int from, int to) {
int dx = pos[from].x - pos[to].x;
int dy = pos[from].y - pos[to].y;
return Math.sqrt(dx*dx + dy*dy);
}
double calc (int cur, int state) {
if(state == full) {
/*Go home*/
return dist(0, cur);
}
if(dp[cur][state] != 0) return dp[cur][state];
dp[cur][state] = Double.MAX_VALUE;
for(int nxt = 1; nxt <= n; ++nxt) {
if(nxt == cur) continue;
int nxt_state = state | shops[nxt];
if(nxt_state > state) {
dp[cur][state] = Math.min(dp[cur][state], dist(cur, nxt) + calc(nxt, nxt_state));
}
}
return dp[cur][state];
}
int toInt(String bin) {
int ret = 0;
for(int i = 0; i < bin.length(); ++i) {
if(bin.charAt(i) == '1')
ret += (1 << (bin.length() - 1 - i));
}
return ret;
}
boolean impossible () {
int total = 0;
for(int i = 1; i <= n; ++i)
total |= shops[i];
return total != full;
}
void Solve(InputReader input, PrintWriter output) {
int testCases = input.nextInt();
for(int test = 0; test < testCases; ++test) {
n = input.nextInt();
k = input.nextInt();
pos = new Point[n+1];
shops = new int[n+1];
full = (1 << k) - 1;
pos[0] = new Point(0, 0);
for(int i = 1; i <= n; ++i) {
int x = input.nextInt();
int y = input.nextInt();
pos[i] = new Point(x, y);
}
for(int i = 1; i <= n; ++i) {
shops[i] = toInt(input.nextWord());
}
if(impossible()) {
output.println("-1");
continue;
}
dp = new double[n+1][1 << k];
output.printf("%.10f\n", calc(0, 0));
}
}
}
static class InputReader {
BufferedReader reader;
StringTokenizer tokenizer;
InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
String nextWord() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
int nextInt() {
return Integer.parseInt(nextWord());
}
long nextLong() {
return Long.parseLong(nextWord());
}
double nextDouble() {
return Double.parseDouble(nextWord());
}
boolean isReady() {
try {
return reader.ready();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}