hihoCoder #1150 Base Station MSBOP 2015 Qualification

Description

A base station has to be built on an N × M grid to serve the users in it.

There are A users in the grid. The cost of serving a user is the square of Euclidean distance between the user and the base station.

The base station also needs maintenance. There are B branches of communication companies in the grid. The cost of maintenance is the Manhattan distance between the base station and the nearest branch.

Please choose the best location for the base station that can minimize the total cost.

Notice that the base station, users, and branches are all on the grid point.

Input

The first line of input contains an integer T, indicating the number of test cases.

Each test case starts with four integers, N, M, A, and B in the first line.

Each of the next A + B lines contains two integers x, y, indicating a grid point. The first A lines specify the locations of users and the last B lines specify the locations of branches.

Output

For each test case, output a line containing "Case #X: Y", where X is the test case number starting from 1 and Y is the minimum total cost described above.

Limits

1 ≤ T ≤ 20

1 ≤ x ≤ N

1 ≤ y ≤ M

1 ≤ B ≤ 100

Small

1 ≤ N, M ≤ 100

1 ≤ A ≤ 100

Large

1 ≤ N, M ≤ 107

1 ≤ A ≤ 1000

 

Sample Input

2
3 3 4 1
1 2
2 1
2 3
3 2
2 2
4 4 4 2
1 2
2 4
3 1
4 3
1 4
1 3

Sample Output

Case #1: 4
Case #2: 13



Solution:

 1 #include <iostream>
 2 #include <cmath>
 3 using namespace std;
 4 
 5 int N, M, CA, CB;
 6 
 7 typedef long long LL;
 8 
 9 struct point {
10     LL x, y;
11 };
12 point *A, *B;
13 
14 
15 LL dd(LL x, LL y) {
16     LL sum = 0;
17     for (int i = 0; i < CA; ++i) {
18         sum += (x-A[i].x) * (x-A[i].x) + (y-A[i].y) * (y-A[i].y);
19     }
20        LL minm = N + M;
21     for (int i = 0; i < CB; ++i) {
22         if (abs(x-B[i].x) + abs(y-B[i].y) < minm) {
23             minm = abs(x-B[i].x) + abs(y-B[i].y);
24         }
25     }
26     return sum + minm;
27 }
28 
29 bool isLocalMin(LL sx, LL sy) {
30     int x_x[] = {0, 0, -1, 1, 1, 1, -1, -1};
31     int y_y[] = {1, -1, 0, 0, 1, -1, 1, -1};
32     for (int i = 0; i < 8; ++i) {
33         if (sx + x_x[i] >= 1 && sx + x_x[i] <= N && sy + y_y[i] >= 1 && sy + y_y[i] <= M)
34         if (dd(sx, sy) > dd(sx+x_x[i], sy+y_y[i]))return false;
35     }
36     return true;
37 }
38 
39 LL findMin() {
40     LL sx = 0, sy = 0;
41     LL sum_x = 0, sum_y =  0;
42     for (int i = 0; i < CA; ++i) {
43         sum_x += A[i].x;
44         sum_y += A[i].y;
45     }
46 
47     sx = sum_x/CA;
48     sy = sum_y/CA;
49 
50     
51     while (!isLocalMin(sx, sy)) {
52         int x_x[] = {0, 0, -1, 1, 1, 1, -1, -1};
53         int y_y[] = {1, -1, 0, 0, 1, -1, 1, -1};
54         int d_x = 0, d_y = 0;
55         for (int i = 0; i < 8; ++i) {
56             if (sx + x_x[i] >= 1 && sx + x_x[i] <= N && sy + y_y[i] >= 1 && sy + y_y[i] <= M)
57             if (dd(sx + d_x, sy + d_y) > dd(sx + x_x[i], sy + y_y[i])) {
58                 d_x = x_x[i];
59                 d_y = y_y[i];
60             }
61         }
62         sx += d_x;
63         sy += d_y;
64     }
65 
66     return dd(sx, sy);
67 }
68 
69 int main() {
70     int T;
71     scanf("%d", &T);
72     for (int k = 1; k <= T; ++k) {
73         scanf("%d%d%d%d", &N, &M, &CA, &CB);
74         A = new point [CA];
75         B = new point [CB];
76         for (int i = 0; i < CA; ++i) {
77             int x,y;
78             scanf("%d%d", &x, &y);
79             A[i].x = x;
80             A[i].y = y;
81         }
82         for (int i = 0; i <  CB; ++i) {
83             int x,y;
84             scanf("%d%d", &x, &y);
85             B[i].x = x;
86             B[i].y = y;
87         }
88         LL cost = findMin();
89         printf("Case #%d: %lld\n", k, cost);
90         delete[] A;
91         delete[] B;
92     }
93 }

 

posted @ 2015-08-22 10:59  HaruHaru  阅读(295)  评论(0)    收藏  举报