The country of jiuye composed by N cites. Each city can be viewed as a point in a two- dimensional plane with integer coordinates (x,y). The distance between city i and city j is defined by d ij = |x i - x j| + |y i - y j|. jiuye want to setup airport in K cities among N cities. So he need your help to choose these K cities, to minimize the maximum distance to the nearest airport of each city. That is , if we define di(1 ≤ i ≤ N ) as the distance from city i to the nearest city with airport. Your aim is to minimize the value max{d i|1 ≤ i ≤ N }. You just output the minimum.
InputThe first line of the input is T (1 ≤ T ≤ 100), which stands for the number of test cases you need to solve.
The first line of each case contains two integers N ,K (1 ≤ N ≤ 60,1 ≤ K ≤ N ),as mentioned above.
The next N lines, each lines contains two integer x i and y i (-10 9 ≤ x i, y i ≤ 10 9), denote the coordinates of city i.OutputFor each test case, print a line “Case #t: ”(without quotes, t means the index of the test case) at the beginning. Then a single integer means the minimum.Sample Input
2 3 2 0 0 4 0 5 1 4 2 0 3 1 0 3 0 8 9
Sample Output
Case #1: 2 Case #2: 4题意:有n块小岛,现在要在其中的k块小岛上建立飞机场,给出小岛的坐标,其中小岛之间的距离d(i,j)=|xi-xj|+|yi-yj|;求建立k个飞机时,飞机的最小航距时多少;思路:二分法判断航距,用DLX重复覆盖判断当前航距下能否满足k座,最后一步步缩小答案。注意岛之间的距离非常大,用long long 存放。代码:
1 #include <cstdio>
2 #include <fstream>
3 #include <algorithm>
4 #include <cmath>
5 #include <deque>
6 #include <vector>
7 #include <queue>
8 #include <string>
9 #include <cstring>
10 #include <map>
11 #include <stack>
12 #include <set>
13 #include <sstream>
14 #include <iostream>
15 #define mod 998244353
16 #define eps 1e-6
17 #define ll long long
18 #define INF 0x3f3f3f3f
19 using namespace std;
20
21 const int maxn=4010;
22 int k;
23 struct
24 {
25 int left[maxn],right[maxn],up[maxn],down[maxn];
26 int head[65],col[maxn];
27 int num[65],id;
28 void init(int m)
29 {
30 for(int i=0;i<=m;i++)
31 {
32 left[i]=i-1;
33 right[i]=i+1;
34 up[i]=down[i]=i;
35 col[i]=i;
36 }
37 id=m;
38 left[0]=m;
39 right[m]=0;
40 memset(head,-1,sizeof(head));
41 memset(num,0,sizeof(num));
42 }
43 void link(int x,int y)
44 {
45 id++;
46 down[id]=down[y];
47 up[down[y]]=id;
48 up[id]=y;
49 down[y]=id;
50 num[y]++;
51 col[id]=y;
52 if(head[x]==-1)
53 {
54 head[x]=left[id]=right[id]=id;
55 }
56 else
57 {
58 right[id]=right[head[x]];
59 left[right[head[x]]]=id;
60 left[id]=head[x];
61 right[head[x]]=id;
62 }
63 }
64 void remove(int c)
65 {
66 for(int i=down[c];i!=c;i=down[i])
67 {
68 left[right[i]]=left[i];
69 right[left[i]]=right[i];
70 }
71 }
72 void reback(int c)
73 {
74 for(int i=up[c];i!=c;i=up[i])
75 {
76 left[right[i]]=right[left[i]]=i;
77 }
78 }
79 bool bj[maxn];
80 int A()
81 {
82 int ans=0;
83 for(int c=right[0];c!=0;c=right[c])
84 {
85 bj[c]=true;
86 }
87 for(int c=right[0];c!=0;c=right[c])
88 {
89 if(bj[c])
90 {
91 ans++;
92 bj[c]=false;
93 for(int i=down[c];i!=c;i=down[i])
94 {
95 for(int j=right[i];j!=i;j=right[j])
96 {
97 bj[col[j]]=false;
98 }
99 }
100 }
101 }
102 return ans;
103 }
104 bool danc(int step)
105 {
106 if(A()+step>k)//剪枝
107 {
108 return false;
109 }
110 if(right[0]==0)
111 {
112 return step<=k;
113 }
114 int c=right[0];
115 for(int i=c;i!=0;i=right[i])
116 {
117 if(num[i]<num[c])
118 {
119 c=i;
120 }
121 }
122 for(int i=down[c];i!=c;i=down[i])
123 {
124 remove(i);
125 for(int j=right[i];j!=i;j=right[j])
126 {
127 remove(j);
128 }
129 if(danc(step+1))
130 {
131 return true;
132 }
133 for(int j=left[i];j!=i;j=left[j])
134 {
135 reback(j);
136 }
137 reback(i);
138 }
139 return false;
140 }
141 }dlx;
142 struct node//小岛信息
143 {
144 ll x,y;
145 }no[65];
146 ll dis(node a,node b)//计算距离
147 {
148 ll dx=a.x-b.x;
149 if(dx<0)
150 {
151 dx=-dx;
152 }
153 ll dy=a.y-b.y;
154 if(dy<0)
155 {
156 dy=-dy;
157 }
158 return dx+dy;
159 }
160 int main()
161 {
162 int t,ans=0;;
163 scanf("%d",&t);
164 while(t--)
165 {
166 ans++;
167 int n;
168 ll x[65],y[65];
169 scanf("%d %d",&n,&k);
170 for(int i=1;i<=n;i++)
171 {
172 scanf("%lld %lld",&no[i].x,&no[i].y);
173 }
174 ll le=0,rig=100000000000LL;
175 while(rig-le>0)
176 {
177 dlx.init(n);
178 ll mid=(rig+le)/2;
179 for(int i=1;i<=n;i++)
180 {
181 for(int j=1;j<=n;j++)
182 {
183 if(dis(no[i],no[j])<=mid)//岛之间的距离比航距小时
184 {
185 dlx.link(i,j);
186 }
187 }
188 }
189 if(dlx.danc(0))//如果当前航距需要的最少飞机的数量比k小为true
190 {
191 rig=mid;
192 }
193 else
194 {
195 le=mid+1;
196 }
197 }
198 printf("Case #%d: %lld\n",ans,le);
199 }
200 }