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;

}

 

 

你可能感兴趣的:(HDU)