Airport
Time Limit: 1500MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u
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
Source
2014 ACM/ICPC Asia Regional Shanghai Online
写过几道DLX之后才发现舞蹈链这个东西其实没那么难,比较灵活的算法,和网络流以及二分图匹配都是需要建图的,把一道题转化成01覆盖模型即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
typedef long long LL;
const int INF=0x3f3f3f3f;
const int maxn = 65;
struct Node
{
int left,right,up,down;
int row,col;
}node[maxn*maxn];
#define left(x) node[x].left
#define right(x) node[x].right
#define up(x) node[x].up
#define down(x) node[x].down
#define row(x) node[x].row
#define col(x) node[x].col
int rows,cols;
int maxnode;
int head;
int tot[maxn];
inline void disable_row(int root)
{
left(right(root)) = left(root);
right(left(root)) = right(root);
}
inline void enable_row(int root)
{
left(right(root)) = root;
right(left(root)) = root;
}
inline void disable_col(int root)
{
up(down(root)) = up(root);
down(up(root)) = down(root);
}
inline void enable_col(int root)
{
up(down(root)) = root;
down(up(root)) = root;
}
inline void remove(int root)
{
for(int i=down(root);i^root;i=down(i))
disable_row(i);
}
inline void restore(int root)
{
for(int i=up(root);i^root;i=up(i))
enable_row(i);
}
int n,k;
inline void initialize()
{
memset(node,0,sizeof(node));
memset(tot,0,sizeof(tot));
rows=0; cols=n;
head=0;
left(head)=cols; right(head)=1;
up(head) = down(head) = 0;
for(int i=1;i<=cols;i++)
{
left(i) = i-1;
right(i) = i+1;
up(i) = down(i) = i;
row(i) = 0;
col(i) = i;
}
right(cols) = head;
maxnode=cols;
}
bool vis[maxn];
inline int h()
{
int ret = 0;
memset(vis,0,sizeof(vis));
for(int i=right(head);i^head;i=right(i))
{
if(vis[i]) continue;
vis[i] = true; ret++;
for(int j=down(i);j^i;j=down(j))
for(int k=right(j);k^j;k=right(k))
vis[col(k)]=true;
}
return ret;
}
bool Dance(int d)
{
if(d+h()>k) return false;
int c1 = right(head);
if(c1 == head) return d<=k;
for(int i=right(c1);i^head;i=right(i))
if(tot[i] < tot[c1]) c1 = i;
if(!tot[c1]) return false;
for(int i=down(c1);i^c1;i=down(i))
{
remove(i);
for(int j=right(i);j^i;j=right(j)) remove(j);
if(Dance(d+1)) return true;
for(int j=left(i);j^i;j=left(j)) restore(j);
restore(i);
}
return false;
}
int a[maxn];
inline void add_row(int cnt)
{
rows++;
for(int i=1;i<=cnt;i++)
{
maxnode++;
if(i==1) left(maxnode)=right(maxnode)=maxnode;
else
{
left(maxnode) = maxnode-1;
right(maxnode) = right(maxnode-1);
enable_row(maxnode);
}
up(maxnode) = up(a[i]);
down(maxnode) = a[i];
enable_col(maxnode);
row(maxnode) = rows;
col(maxnode) = a[i];
tot[a[i]]++;
}
}
struct Point
{
int x,y;
inline void read() { scanf("%d%d",&x,&y); }
}point[maxn];
inline LL dist(Point a,Point b)
{
LL t1 = abs(b.x - a.x);
LL t2 = abs(b.y - a.y);
return t1+t2;
}
void init()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) point[i].read();
}
bool judge(LL lim)
{
initialize();
for(int i=1;i<=n;i++)
{
int cnt = 0;
for(int j=1;j<=n;j++)
if(dist(point[i],point[j]) <= lim) a[++cnt] = j;
if(cnt) add_row(cnt);
}
return Dance(0);
}
LL work()
{
LL l = 0 , r = 4*1e9+5;
while(l<r)
{
LL m = (l+r)>>1;
bool tmp = judge(m);
if(tmp) r = m;
else l = m + 1;
}
return l;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("air.in","r",stdin);
freopen("air.out","w",stdout);
#endif
int cas = 0;
int T;
scanf("%d",&T);
while(T--)
{
init();
LL ans = work();
printf("Case #%d: " AUTO "\n",++cas,ans);
}
return 0;
}