hdu2295Radar [dancing links重复覆盖]


Problem Description
N cities of the Java Kingdom need to be covered by radars for being in a state of war. Since the kingdom has M radar stations but only K operators, we can at most operate K radars. All radars have the same circular coverage with a radius of R. Our goal is to minimize R while covering the entire city with no more than K radars.
 

Input
The input consists of several test cases. The first line of the input consists of an integer T, indicating the number of test cases. The first line of each test case consists of 3 integers: N, M, K, representing the number of cities, the number of radar stations and the number of operators. Each of the following N lines consists of the coordinate of a city.
Each of the last M lines consists of the coordinate of a radar station.

All coordinates are separated by one space.
Technical Specification

1. 1 ≤ T ≤ 20
2. 1 ≤ N, M ≤ 50
3. 1 ≤ K ≤ M
4. 0 ≤ X, Y ≤ 1000
 

Output
For each test case, output the radius on a single line, rounded to six fractional digits.
 

Sample Input
   
   
   
   
1 3 3 2 3 4 3 1 5 4 1 1 2 2 3 3
 

Sample Output
   
   
   
   
2.236068
 

Source
The 4th Baidu Cup final
 

状态奇差的一个晚上==

dancing links除了可以解决精确覆盖之外还可以解决的一类覆盖问题叫做重复覆盖,精确覆盖解决的是在0、1矩阵中删除一些行,使得剩下的矩阵可以每列都有且只有一个“1”,而重复覆盖是指删除一些行,使得每列都有“1”。拿到这个题里来说就是删除一些基站使得城市依旧能够被覆盖。重复覆盖的模板理解的不是十分透彻 QAQ remove resume由于不需要满足“有且只有”的条件,精简了好多,网上也没有比较详细的重复覆盖

/************************************************
hdu2295
2016.3.6
140MS	1808K	3559B	C++
*************************************************/

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int maxnode = 3000;
const int MaxM = 55;
const int MaxN = 55;
int K;
struct DLX
{
    int n,m,size;
    int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
    int H[MaxN],S[MaxN];
    int ands,ans[MaxN];
    void init(int _n,int _m)
    {
        n = _n;
        m = _m;
        for(int i = 0;i <= m;i++)
        {
            S[i] = 0;
            U[i] = D[i] = i;
            L[i] = i-1;
            R[i] = i+1;
        }
        R[m] = 0; L[0] = m;
        size = m;
        for(int i = 1;i <= n;i++)
            H[i] = -1;
    }
    void Link(int r,int c)
    {
        ++S[Col[++size]=c];
        Row[size] = r;
        D[size] = D[c];
        U[D[c]] = size;
        U[size] = c;
        D[c] = size;
        if(H[r] < 0)H[r] = L[size] = R[size] = size;
        else
        {
            R[size] = R[H[r]];
            L[R[H[r]]] = size;
            L[size] = H[r];
            R[H[r]] = size;
        }
    }
    void remove(int c)
    {
        for(int i = D[c];i != c;i = D[i])
            L[R[i]] = L[i], R[L[i]] = R[i];
    }
    void resume(int c)
    {
        for(int i = U[c];i != c;i = U[i])
            L[R[i]]=R[L[i]]=i;
    }
    bool v[maxnode];
    int f()
    {
        int ret = 0;
        for(int c = R[0];c != 0;c = R[c])v[c] = true;
        for(int c = R[0];c != 0;c = R[c])
            if(v[c])
            {
                ret++;
                v[c] = false;
                for(int i = D[c];i != c;i = D[i])
                    for(int j = R[i];j != i;j = R[j])
                        v[Col[j]] = false;
            }
        return ret;

    }
    bool Dance(int d)
    {
        if(d + f() > K)return false;
        if(R[0] == 0)return d <= K;
        int c = R[0];
        for(int i = R[0];i != 0;i = R[i])
            if(S[i] < S[c])
                c = i;
        for(int i = D[c];i != c;i = D[i])
        {
            remove(i);
            for(int j = R[i];j != i;j = R[j])remove(j);
            if(Dance(d+1))return true;
            for(int j = L[i];j != i;j = L[j])resume(j);
            resume(i);
        }
        return false;
    }
};
DLX g;
const double eps = 1e-8;
struct node
{
    int x,y;
    void input()
    {
        scanf("%d%d",&x,&y);
    }
}station[MaxN],city[MaxM];
double cal(node a,node b)
{
    return sqrt(double((a.x-b.x)*(a.x-b.x))+double((a.y-b.y)*(a.y-b.y)));
}
int main()
{
   // freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int T;
    int n,m;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&K);
        for(int i=1;i<=n;i++) city[i].input();
        for(int i=1;i<=m;i++) station[i].input();
        double l=0,r=1e8,mid;
        while(r-l>=eps)
        {
            mid=(l+r)/2;
            g.init(m,n);
            for(int i=1;i<=m;i++)
                for(int j=1;j<=n;j++)
                    if(cal(station[i],city[j])<mid-eps)
                        g.Link(i,j);
            if(g.Dance(0)) r=mid-eps;
            else l=eps+mid;
        }
        printf("%.6lf\n",l);
    }
    return 0;
}


你可能感兴趣的:(hdu2295Radar [dancing links重复覆盖])