HDU 5046 Airport [DLX] [RepeatCover]

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;
}
發佈了148 篇原創文章 · 獲贊 5 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章