hdu 2295 DLX

思路:裸的DLX重复覆盖

#include<set>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<string>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pb push_back
#define mp make_pair
#define Maxn 51
#define Maxm 80002
#define LL __int64
#define Abs(x) ((x)>0?(x):(-x))
#define lson(x) (x<<1)
#define rson(x) (x<<1|1)
#define inf 1000000
#define lowbit(x) (x&(-x))
#define clr(x,y) memset(x,y,sizeof(x))
#define Mod 1000000007
using namespace std;
int D[Maxn*Maxn],U[Maxn*Maxn],L[Maxn*Maxn],R[Maxn*Maxn],S[Maxn*Maxn],C[Maxn*Maxn],H[Maxn],id,K,n,m,cnt;
bool vi[Maxn];
struct Point{
    double x,y;
}city[Maxn],rader[Maxn];
double dis[Maxn][Maxn],edge[Maxn*Maxn];
double Dis(Point a,Point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
void init(int m)
{
    int i;
    for(i=0;i<=m;i++){
        D[i]=U[i]=i;
        L[i+1]=i;
        R[i]=i+1;
        S[i]=0;
    }
    R[m]=0;
    id=m+1;
}
void ins(int r, int c)
{
    U[id] = c;
    D[id] = D[c];
    U[D[c]] = id;
    D[c] = id;
    if (H[r] < 0)
        H[r] = L[id] = R[id] = id;
    else
    {
        L[id] = H[r];
        R[id] = R[H[r]];
        L[R[H[r]]] = id;
        R[H[r]] = id;
    }
    S[c]++;
    C[id++] = c;
}
void Remove(int c)
{
    int i;
    for(i=D[c];i!=c;i=D[i]){
        L[R[i]]=L[i];
        R[L[i]]=R[i];
    }
}
void Resume(int c)
{
    int i;
    for(i=D[c];i!=c;i=D[i]){
        L[R[i]]=i;
        R[L[i]]=i;
    }
}
int A()
{
    int i,j,k,ret=0;
    memset(vi,false,sizeof(vi));
    for(i=R[0];i;i=R[i]) if(!vi[i]){
        ret++;
        for(j=D[i];j!=i;j=D[j]){
            for(k=R[j];k!=j;k=R[k])
                vi[C[k]]=true;
        }
    }
    return ret;
}
int dfs(int step)
{
    if(step+A()>K) return false;
    if(R[0]==0) return true;
    int i,j,temp,c;
    temp=inf;
    for(i=R[0];i;i=R[i]) if(S[i]<temp){
        temp=S[i];
        c=i;
    }
    for(i=D[c];i!=c;i=D[i]){
        Remove(i);
        for(j=R[i];j!=i;j=R[j]){
            Remove(j);
        }
        if(dfs(step+1))
            return true;
        for(j=R[i];j!=i;j=R[j])
            Resume(j);
        Resume(i);
    }
    return false;
}
void build(int pos)
{
    int i,j;
    init(n);
    for(i=1;i<=m;i++){
        H[i]=-1;
        for(j=1;j<=n;j++){
            if(dis[i][j]<=edge[pos])
                ins(i,j);
        }
    }
}
void solve()
{
    int i,j,l,r,mid;
    l=1,r=cnt;
    while(l<r){
        mid=(l+r)>>1;
        build(mid);
        if(dfs(0))
            r=mid;
        else
            l=mid+1;
    }
    printf("%.6lf\n",edge[l]);
}
int main()
{
    int t,i,j;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d",&n,&m,&K);
        for(i=1;i<=n;i++)
            scanf("%lf%lf",&city[i].x,&city[i].y);
        for(i=1;i<=m;i++)
            scanf("%lf%lf",&rader[i].x,&rader[i].y);
        cnt=0;
        for(i=1;i<=m;i++)
        for(j=1;j<=n;j++){
            dis[i][j]=Dis(rader[i],city[j]);
            edge[++cnt]=dis[i][j];
        }
        sort(edge+1,edge+1+cnt);
        int num=1;
        for(i=2;i<=cnt;i++) if(edge[i]!=edge[num]){
            edge[++num]=edge[i];
        }
        cnt=num;
        solve();
    }
    return 0;
}

 

 

posted @ 2013-09-09 11:57  fangguo  阅读(160)  评论(0编辑  收藏  举报