[HDU5046] Airport

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 }

 

posted @ 2017-07-14 20:21  人棍王楼下的AI  阅读(184)  评论(0编辑  收藏  举报