Description
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 d i(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.
Input
The 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.
Output
For 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
首先二分最大距离,对于每个距离采用舞蹈链算法判断其是否满足要求
代码如下
1 #include<bits/stdc++.h> 2 #define FOR(i,p,X) for(int i=X[p];i!=p;i=X[i]) 3 #define For(i,a,b) for(int i=(a),i_end=(b);i<=i_end;++i) 4 using namespace std; 5 const int N=70; 6 int n,m,ans; 7 vector<int>G[N]; 8 struct DLX{ 9 int L[N*N],R[N*N],U[N*N],D[N*N]; 10 int C[N*N],H[N],cnt[N],vis[N],id; 11 void init(){ 12 For(i,0,n){ 13 cnt[i]=0;U[i]=D[i]=i; 14 L[i+1]=i;R[i]=i+1; 15 } 16 R[n]=0;id=n+1; 17 memset(H,-1,sizeof(H)); 18 } 19 void Link(int r,int c){ 20 cnt[c]++;C[id]=c; 21 U[id]=U[c];D[U[c]]=id; 22 D[id]=c;U[c]=id; 23 if(!~H[r]) H[r]=L[id]=R[id]=id; 24 else{ 25 L[id]=L[H[r]];R[L[H[r]]]=id; 26 R[id]=H[r];L[H[r]]=id; 27 } 28 id++; 29 } 30 void Remove(int sz){ 31 FOR(j,sz,D)L[R[j]]=L[j],R[L[j]]=R[j]; 32 } 33 void Resume(int sz){ 34 FOR(j,sz,D)L[R[j]]=R[L[j]]=j; 35 } 36 int h(){ 37 int res=0; 38 memset(vis,0,sizeof(vis)); 39 FOR(i,0,R){ 40 if(vis[i])continue; 41 ++res; 42 FOR(j,i,D)FOR(k,j,R) 43 vis[C[k]]=1; 44 } 45 return res; 46 } 47 bool Dance(int k){ 48 if(k+h()>m)return false; 49 int pos=R[0]; 50 if(!pos)return k<=m; 51 FOR(i,0,R)if(cnt[pos]>cnt[i])pos=i; 52 FOR(i,pos,D){ 53 Remove(i); 54 FOR(j,i,R)Remove(j); 55 if(Dance(k+1))return true; 56 FOR(j,i,R)Resume(j); 57 Resume(i); 58 } 59 return false; 60 } 61 }dlx; 62 struct Point{ 63 int x,y; 64 void input(){ 65 scanf("%d%d",&x,&y); 66 } 67 }city[N]; 68 long long dis(Point a,Point b){ 69 return (long long)abs(a.x-b.x)+(long long)abs(a.y-b.y); 70 } 71 int main(){ 72 int T; 73 scanf("%d",&T); 74 For(iCase,1,T){ 75 scanf("%d%d",&n,&m); 76 For(i,1,n)city[i].input(); 77 long long l=0,r=100000000000LL; 78 long long ans=0; 79 while(l<=r){ 80 long long mid=l+r>>1; 81 dlx.init(); 82 For(i,1,n)For(j,1,n) 83 if(dis(city[i],city[j])<=mid) 84 dlx.Link(i,j); 85 if(dlx.Dance(0))r=(ans=mid)-1; 86 else l=mid+1; 87 } 88 printf("Case #%d: %I64d\n",iCase,ans); 89 } 90 return 0; 91 }