hdu 2298 Radar 重复覆盖

#include <bits/stdc++.h>
using namespace std;
struct DLX
{
    const static int maxn=64,maxm=64,maxnode=maxn*maxn;
    int n,m,sz,anssz;
    int u[maxnode],d[maxnode],l[maxnode],r[maxnode],row[maxnode],col[maxnode];
    //row col 记录该节点i坐标
    int h[maxn],colcnt[maxm];
    void init(int _n,int _m) //数据位于1,1...n,m
    {
        n=_n,m=_m;
        for(int i=0;i<=m;i++)//1..m是每一列的辅助结点 0代表(0,0)即head
        {
            u[i]=d[i]=i;
            l[i]=i-1;r[i]=i+1;
            col[i]=i;row[i]=0;
            colcnt[i]=0;
        }
        l[0]=m;r[m]=0;
        sz=m;anssz=INT_MAX;
        for(int i=1;i<=n;i++)h[i]=-1;
    }
    void push(int x,int y)
    {
        colcnt[y]++;
        col[++sz]=y;
        row[sz]=x;
        d[sz]=d[y]; //加入列首元素后面
        u[sz]=y;
        u[d[y]]=sz;
        d[y]=sz;
        if(h[x]<0) h[x]=r[sz]=l[sz]=sz; //成为行首元素
        else{
            int hd=h[x]; //加入行首节点右边
            l[sz]=hd;
            r[sz]=r[hd];
            l[r[hd]]=sz;
            r[hd]=sz;
        }
    }
    void repeat_remove(int x){
        for(int i=d[x];i!=x;i=d[i])
            l[r[i]]=l[i],r[l[i]]=r[i];
    }
    void repeat_resume(int x){
        for(int i=u[x];i!=x;i=u[i])
            l[r[i]]=r[l[i]]=i;
    }
    int H(){
        static bool vis[maxm];
        memset(vis,0,sizeof vis);
        int res=0;
        for(int i=r[0];i!=0;i=r[i]){ //如果该列未被标标记,则标记该列中每行的列
            if(vis[i]) continue;
            res++;vis[i]=1;
            for(int j=d[i];j!=i;j=d[j])
                for(int k=r[j];k!=j;k=r[k]) vis[col[k]]=1;
         }
        return res;//易证res <= ans-dep
    }
    void repeat_dance(int dep)
    {
        if(r[0]==0){
            anssz=min(anssz,dep); return ;
        }
        if(dep+H()>=anssz) return ;
        int cur=r[0];
        for(int i=r[0];i!=0;i=r[i]) if(colcnt[i]<colcnt[cur])cur=i;
//        repeat_remove(cur);
        for(int i=d[cur];i!=cur;i=d[i]){
            repeat_remove(i);
            for(int j=r[i];j!=i;j=r[j]) repeat_remove(j);
            repeat_dance(dep+1);
            for(int j=l[i];j!=i;j=l[j]) repeat_resume(j);
            repeat_resume(i);
        }
//        repeat_resume(cur);
    }
};
DLX dlx;
struct point{
    double x,y;
    double dis(const point &a)
    {
        return hypot(a.x-x,a.y-y);
    }
};
point city[64],radar[64];
bool le(double a,double b)
{
    if(a<b)return true;
}
int main()
{
#ifdef shuaishuai
    freopen("in.txt","r",stdin);
#endif // shuaishuai
//二分裸重复覆盖
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<n;i++)scanf("%lf%lf",&city[i].x,&city[i].y);
        for(int i=0;i<m;i++)scanf("%lf%lf",&radar[i].x,&radar[i].y);
        double l=0,r=2000;
        do{
            double mi=(l+r)/2;
            static bool vis[64];
            memset(vis,0,sizeof vis);
            int cnt=0;
            dlx.init(m,n);
            for(int i=0;i<m;i++)for(int j=0;j<n;j++)
            if(radar[i].dis(city[j])<=mi){
                if(!vis[j]) vis[j]=true,cnt++;
                dlx.push(i+1,j+1);
            }
            if(cnt!=n) {l=mi;continue;}
            dlx.repeat_dance(0);
            if(dlx.anssz>k) l=mi;
            else r=mi;
        }while(r-l>1e-7);
        printf("%.6f\n",(l+r)/2);
    }
    return 0;
}

 

posted @ 2018-10-09 02:50  BIack_Cat  阅读(140)  评论(0编辑  收藏  举报