zoukankan      html  css  js  c++  java
  • HDU 2295 Radar dancing links 重复覆盖

    就是dancing links 求最小支配集,重复覆盖

    精确覆盖时:每次缓存数据的时候,既删除行又删除列(这里的删除列,只是删除表头)

    重复覆盖的时候:只删除列,因为可以重复覆盖

    然后重复覆盖有一个估价函数,这个函数很强大,可以进行强力剪枝

    这个估价函数的意思是,搜索到当前时,至少还需要删除几行,就可以完全覆盖了

    这个至少得意思是最优删:

    选择一列,假设覆盖这一列的有许多行,假设这些行覆盖的所有列都是一行覆盖的,然后记录数量

    然后重复操作,直到全部覆盖,所以这个数量就是最少要的数量

    (估价函数很重要)

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<cstdlib>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    const int N=3000;
    const double eps=1e-8;
    int n,m,sz,k;
    int u[N],l[N],r[N],d[N];
    int h[55],s[55],col[N];
    void init()
    {
        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;
        sz=m;
        for(int i=1; i<=n; ++i)
            h[i]=-1;
    }
    void link(int x,int y)
    {
        ++sz;
        ++s[y],col[sz]=y;
        u[sz]=u[y],d[u[y]]=sz;
        d[sz]=y,u[y]=sz;
        if(h[x]==-1)h[x]=l[sz]=r[sz]=sz;
        {
            l[sz]=l[h[x]];
            r[l[h[x]]]=sz;
            r[sz]=h[x];
            l[h[x]]=sz;
        }
    }
    void del(int y)
    {
        for(int i=d[y]; i!=y; i=d[i])
            r[l[i]]=r[i],l[r[i]]=l[i];
    }
    void resume(int y)
    {
        for(int i=d[y]; i!=y; i=d[i])
            r[l[i]]=l[r[i]]=i;
    }
    bool vis[55];
    int f()
    {
        int ret=0;
        for(int i=r[0]; i; i=r[i])
            vis[i]=0;
        for(int i=r[0]; i; i=r[i])
        {
            if(vis[i])continue;
            vis[i]=1;
            ++ret;
            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 ret;
    }
    bool dance(int pos)
    {
        if(pos+f()>k)return 0;
        if(!r[0])
        {
            if(pos<=k)return 1;
            return 0;
        }
        int t=r[0];
        for(int i=r[0]; i!=0; i=r[i])
            if(s[i]<s[t])t=i;
        for(int i=d[t]; i!=t; i=d[i])
        {
            del(i);
            for(int j=r[i]; j!=i; j=r[j])
                del(j);
            if(dance(pos+1))return 1;
            for(int j=l[i]; j!=i; j=l[j])
                resume(j);
            resume(i);
        }
        return 0;
    }
    struct Point
    {
       double x,y;
    }b[55],e[55];
    double dis(int i,int j)
    {
       return sqrt((b[i].x-e[j].x)*(b[i].x-e[j].x)+(b[i].y-e[j].y)*(b[i].y-e[j].y));
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d",&n,&m,&k);
            swap(n,m);
            for(int i=1;i<=m;++i)
              scanf("%lf%lf",&e[i].x,&e[i].y);
            for(int i=1;i<=n;++i)
              scanf("%lf%lf",&b[i].x,&b[i].y);
            double low=0,high=1e6;
            while(high-low>=eps)
            {
               double mid=(high+low)/2.0;
               init();
               for(int i=1;i<=n;++i)
                for(int j=1;j<=m;++j)
                 if(dis(i,j)<=mid)
                     link(i,j);
               if(dance(0))high=mid;
               else low=mid;
            }
            low=(high+low)/2;
            printf("%.6f
    ",low);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    实验四附加实验 项目互评
    201671010413葛进花+《英文文本统计分析》结对项目报告
    201671010413葛进花 词频统计软件项目报告
    201671010413葛进花实验三作业互评与改进报告
    实验一 软件工程准备
    201671010418 刘佳 实验十四 团队项目评审&课程学习总结
    201671010418 刘佳 实验四附加实验 项目互评
    201671010418 刘佳 《英文文本统计分析》结对项目报告
    201671010418刘佳 实验二词频统计项目报告
    201671010418刘佳 实验三作业互评与改进报告
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5288088.html
Copyright © 2011-2022 走看看