您的位置:首页 > 理论基础 > 计算机网络

HDU 5046 Airport (2014年上海赛区网络赛E题)

2015-09-08 22:09 387 查看
1.题目描述:点击打开链接

2.解题思路:本题利用二分+DLX(重复覆盖型)解决。首先,看到最大值最小化,肯定是用二分法解决。但是没有想到的是这题是重复覆盖的模板题==(见识短浅了。。一直在想dfs)。在DLX算法中,关键要明确行和列分别如何确定。显然,这里的行是可能当做机场的城市,列是与该城市距离小于给定的M的城市。这样就可以利用DLX算法了,同时,这道题还可以加上一个剪枝,如果发现剩下的未被覆盖的城市需要建机场的数目h与当前的递归层数d之和大于k,那么就可以直接剪枝了。

3.代码:

#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<bitset>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<complex>
#include<functional>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define me(s)  memset(s,0,sizeof(s))
#define rep(i,n) for(int i=0;i<(n);i++)
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair <int, int> P;

const int maxnode=4005;
const int maxm=65;
const int maxn=65;
const int INF=0x3f3f3f3f;

int k;
struct DLX
{
    int n,m,size;
    int U[maxnode],D[maxnode],R[maxnode],L[maxnode];
    int row[maxnode],col[maxnode];
    int head[maxn],S[maxnode];
    int ansd,ans[maxn];

    void init(int n,int m)
    {
        this->n=n;
        this->m=m;
        ansd=INF;
        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;
        memset(head,-1,sizeof(int)*(n+1));
    }
    void addRow(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(head[r]<0)head[r]=L[size]=R[size]=size;
       else
       {
           R[size]=R[head[r]];
           L[R[head[r]]]=size;
           L[size]=head[r];
           R[head[r]]=size;
       }
    }
    #define FOR(i,A,s) for(int i=A[s];i!=s;i=A[i])
    void remove(int c)
    {
        FOR(i,D,c)
        L[R[i]]=L[i],R[L[i]]=R[i];
    }
    void restore(int c)
    {
        FOR(i,U,c)
        L[R[i]]=R[L[i]]=i;
    }

    int v[maxnode];
    int h()
    {
        int ret=0;
        FOR(i,R,0)v[i]=1;
        FOR(c,R,0)
        if(v[c])
        {
            ret++;
            v[c]=0;
            FOR(i,D,c)FOR(j,R,i)v[col[j]]=0;
        }
        return ret;
    }

    bool dfs(int d)
    {
        if(d+h()>k)return false;
        if(!R[0]) return d<=k;
        int c=R[0];
        FOR(i,R,0)if(S[i]<S[c])c=i;

        FOR(i,D,c)
        {
            remove(i);
            FOR(j,R,i)remove(j);
            ans[d]=row[i];
            if(dfs(d+1))return true;
            FOR(j,L,i)restore(j);
            restore(i);
        }
        return false;
    }
};

DLX solver;

int T,n;
const int N=65;

struct City
{
    ll x,y;
    void read()
    {
        scanf("%I64d%I64d",&x,&y);
    }
}c
;

ll dis(City a,City b)
{
    return abs(a.x-b.x)+abs(a.y-b.y);
}

int main()
{
    int rnd=0;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
            c[i].read();
        ll L=0,R=10000000000LL;
        while(L<R)
        {
            ll M=(L+R)/2;
            solver.init(n,n);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                if(dis(c[i],c[j])<=M)
                solver.addRow(i,j);
            if(solver.dfs(0))R=M;
            else L=M+1;
        }
        printf("Case #%d: %I64d\n",++rnd,L);
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: