还有13天NOI,把各种乱七八糟的算法都重新过一遍还是比较有必要的。。。

 

//HDU 5046 Airport
//DancingLink
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 110
#define MAXD MAXN*MAXN
#define INF 0x3f3f3f3f
#define LL "%lld"
typedef long long qword;
struct point
{
        qword x,y;
};
point pl[MAXN];
qword dis(point p1,point p2)
{
        return abs(p1.x-p2.x)+abs(p1.y-p2.y);
}
int L[MAXD],R[MAXD],U[MAXD],D[MAXD];
int ptr[MAXN];
int tot[MAXN];
int col[MAXD];
int topd=0;
int head=0;
void cover(int now)
{
        for (int i=R[now];i!=now;i=R[i])
        {
                for (int j=U[i];j!=i;j=U[j])
                {
                        L[R[j]]=L[j];
                        R[L[j]]=R[j];
                }
        }
        for (int j=U[now];j!=now;j=U[j])
        {
                L[R[j]]=L[j];
                R[L[j]]=R[j];
        }
}
void recover(int now)
{
        for (int i=R[now];i!=now;i=R[i])
                for (int j=U[i];j!=i;j=U[j])
                        L[R[j]]=R[L[j]]=j;
        for (int j=U[now];j!=now;j=U[j])
                L[R[j]]=R[L[j]]=j;
}
int vv[MAXN];
int ff()
{
        int ret=0;
        for (int i=R[head];i!=head;i=R[i])
                vv[col[i]]=true;
        for (int i=R[head];i!=head;i=R[i])
        {
                if (vv[col[i]])
                {
                        ret++;
                        for (int j=D[i];j!=i;j=D[j])
                        {
                                for (int k=R[j];k!=j;k=R[k])
                                {
                                        vv[col[k]]=false;
                                }
                        }
                }
        }
        return ret;
}
bool solve(int trst)
{
        if (L[head]==R[head] && L[head]==head)return true;
        if (!trst)return false;
        if (trst<ff())return false;
        pair<int,int> mnv=make_pair(INF,0);
        for (int i=R[head];i!=head;i=R[i])
                mnv=min(mnv,make_pair(tot[i],i));
        int now=mnv.second;
        for (int i=D[now];i!=now;i=D[i])
        {
                cover(i);
                if (solve(trst-1))return true;
                recover(i);
        }
        return false;
}

int main()
{
        freopen("input.txt","r",stdin);
        int nn;
        int n,m;
        int x,y,z;
        scanf("%d",&nn);
        int caseid=0;
        while (nn--)
        {
                caseid++;
                scanf("%d%d",&n,&m);
                for (int i=1;i<=n;i++)
                        scanf(LL LL ,&pl[i].x,&pl[i].y);
                memset(ptr,0,sizeof(ptr[0])*(n+10));
                memset(tot,0,sizeof(tot[0])*(n+10));
                qword l=-1,r=1ll<<33,mid;
                while (l+1<r)
                {
                        mid=(l+r)>>1;
                        topd=0;
                        head=++topd;
                        L[head]=R[head]=head;
                        for (int i=1;i<=n;i++)
                        {
                                int np=++topd;
                                col[np]=i;
                                R[np]=head;
                                L[np]=L[head];
                                L[R[np]]=np;
                                R[L[np]]=np;
                                D[np]=U[np]=np;
                                ptr[i]=np;
                        }
                        for (int i=1;i<=n;i++)
                        {
                                int last=0;
                                for (int j=1;j<=n;j++)
                                {
                                        if (dis(pl[i],pl[j])<=mid)
                                        {
                                                int np=++topd;
                                                col[np]=j;
                                                tot[ptr[j]]++;
                                                D[np]=ptr[j];
                                                U[np]=U[ptr[j]];
                                                D[U[np]]=U[D[np]]=np;
                                                if (!last)
                                                {
                                                        L[np]=R[np]=np;
                                                }else
                                                {
                                                        L[np]=last;
                                                        R[np]=R[last];
                                                        L[R[np]]=R[L[np]]=np;
                                                }
                                                last=np;
                                        }
                                }
                        }
                        if (solve(m))
                        {
                                r=mid;
                        }else
                        {
                                l=mid;
                        }
                }
                printf("Case #%d: "LL"\n",caseid,r);
        }
}
DancingLink

相关文章:

  • 2021-08-29
  • 2020-03-02
  • 2021-07-17
  • 2022-03-03
  • 2022-12-23
  • 2022-12-23
  • 2021-12-05
猜你喜欢
  • 2021-08-31
  • 2021-09-17
  • 2021-08-03
  • 2021-06-16
  • 2021-06-19
  • 2022-12-23
  • 2021-11-28
相关资源
相似解决方案