首页 > 代码库 > (中等) HDU 5046 Airport ,DLX+可重复覆盖+二分。

(中等) HDU 5046 Airport ,DLX+可重复覆盖+二分。

  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.
 
  题目是最大值最小化,明显的二分,然后对于每一个值,判断能不能找到K个以内的来覆盖。。。。。。
 
  做的时候要注意二分的问题,还有就是要用long long 别用int,还有就是abs。。。不知道怎么回事被坑了,自己写了一个abs来用的。。。。。。
 
技术分享
#include<iostream>#include<cstring>#include<utility>#include<algorithm>using namespace std;const int MaxN=70;const int MaxM=70;const int MaxNode=MaxN*MaxM;int N,K;long long X[70],Y[70];long long abs1(long long x){    if(x<0)        x=-x;    return x;}struct DLX{    int U[MaxNode],D[MaxNode],L[MaxNode],R[MaxNode],col[MaxNode];    int S[MaxM],H[MaxN];    int size,m,n;    void init(int _n,int _m)    {        n=_n;        m=_m;        size=m;        for(int i=0;i<=m;++i)        {            U[i]=D[i]=i;            L[i]=i-1;            R[i]=i+1;            S[i]=0;        }        L[0]=m;        R[m]=0;        for(int i=0;i<=n;++i)            H[i]=-1;    }    void Link(int r,int c)    {        col[++size]=c;        ++S[c];        U[size]=U[c];        D[size]=c;        D[U[c]]=size;        U[c]=size;        if(H[r]==-1)            H[r]=L[size]=R[size]=size;        else        {            L[size]=L[H[r]];            R[size]=H[r];            R[L[H[r]]]=size;            L[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 vis[MaxM];    int getH()    {        int ret=0;        for(int i=R[0];i;i=R[i])            vis[i]=1;        for(int c=R[0];c;c=R[c])            if(vis[c])            {                ++ret;                vis[c]=0;                for(int i=D[c];i!=c;i=D[i])                    for(int j=R[i];j!=i;j=R[j])                        vis[col[j]]=0;            }        return ret;    }    bool Dance(int d)    {        if(d+getH()>K)            return 0;        if(R[0]==0)            return d<=K;        int c=R[0];        for(int i=R[0];i;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 1;            for(int j=L[i];j!=i;j=L[j])                resume(j);            resume(i);        }        return 0;    }};pair <long long,int> rem[70][70];long long remP[70];DLX dlx;void slove(long long maxNum){    long long L=0,R=maxNum,M,ans;    for(int i=1;i<=N;++i)    {        for(int j=1;j<=N;++j)        {            rem[i][j].first=(long long)abs1(X[i]-X[j])+(long long)abs1(Y[i]-Y[j]);            rem[i][j].second=j;        }        sort(rem[i]+1,rem[i]+N+1);        remP[i]=1;    }/*    dlx.init(N,N);    for(M=L;M<=R;++M)    {        for(int i=1;i<=N;++i)            while(rem[i][remP[i]].first<=M)            {                dlx.Link(i,rem[i][remP[i]].second);                ++remP[i];            }        if(dlx.Dance(0))            break;    }*/    while(R>L)    {        M=(L+R)/2;        dlx.init(N,N);        for(int i=1;i<=N;++i)            for(int j=1;j<=N;++j)                if(rem[i][j].first<=M)                    dlx.Link(i,rem[i][j].second);                else                    break;        if(dlx.Dance(0))            R=M;        else            L=M+1;    }    cout<<L<<endl;}int main(){    ios::sync_with_stdio(false);    int T;    long long maxX,maxY,minX,minY;    cin>>T;    for(int cas=1;cas<=T;++cas)    {        cin>>N>>K;        cin>>X[1]>>Y[1];        maxX=minX=X[1];        maxY=minY=Y[1];        for(int i=2;i<=N;++i)        {            cin>>X[i]>>Y[i];            if(maxX<X[i])                maxX=X[i];            if(maxY<Y[i])                maxY=Y[i];            if(minX>X[i])                minX=X[i];            if(minY>Y[i])                minY=Y[i];        }        cout<<"Case #"<<cas<<": ";        slove(maxX+maxY-minX-minY);    }    return 0;}
View Code

 

(中等) HDU 5046 Airport ,DLX+可重复覆盖+二分。