标签:
这题题意是 给了n个城市 在其中小于等于k个城市建立机场然后 使得最远的那个离机场的城市距离最短
二分答案 ,我们对于每次的mid 重新建图然后再来一次DLX,每个点可以覆盖的点建立一条联系就ok了
#include <iostream> #include <algorithm> #include <cstdio> #include <string.h> #include <vector> using namespace std; const int maxn=61; const int maxnode=61*61; int K; struct DLX { int numCol,numRow,U[maxnode],D[maxnode],L[maxnode],R[maxnode],row[maxnode],col[maxnode]; int S[maxn],H[maxn],siz; void init(int n,int m) { this->numCol=n; this->numRow=m; for(int i=0; i<=numCol; i++) { S[i]=0; U[i]=D[i]=i; L[i]=i-1; R[i]=i+1; } L[0]=n; R[n]=0; for(int i=0; i<=numRow; i++)H[i]=-1; siz=n+1; } void link(int r, int c) { S[c]++; row[siz]=r; col[siz]=c; U[siz]=U[c]; D[siz]=c; D[U[siz]]=siz; U[D[siz]]=siz; if(H[r]==-1){ H[r]=L[siz]=R[siz]=siz; }else { L[siz]=H[r]; R[siz]=R[H[r]]; R[L[siz]]=siz; L[R[siz]]=siz; H[r]=siz; } siz++; } bool v[maxnode]; int AX() { for(int c=R[0]; c!=0; c=R[c])v[c]=true; int ret=0; for(int c=R[0]; c!=0; c=R[c]) if(v[c]) { ret++; v[c]=false; for(int i=D[c];i!=c; i=D[i]) for(int j=R[i]; j!=i; j=R[j]) v[col[j]]=false; } return ret; } 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 Dance(int d) { if(AX()+d>K)return false; if(R[0]==0)return d<=K; int c=R[0]; for(int i=R[0]; i!=0; 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 true; for(int j=L[ i ]; j!=i; j=L[ j ])resume( j ); resume( i ); } return false; } }g; struct point { int x,y; void input() { scanf("%d%d",&x,&y); } }city[maxn]; long long dis(point a, point b) { return (long long)abs(a.x-b.x)+(long long)abs(a.y-b.y); } int main() { int cas; scanf("%d",&cas); for(int cc=1; cc<=cas; cc++) { int n; scanf("%d%d",&n,&K); for(int i=0; i<n; i++) city[i].input(); long long L=0,R=100000000000LL; long long ans=0; while(L<=R) { long long mid=(L+R)>>1; g.init(n,n); for(int i=0;i<n;i++) for(int j=0; j<n;j++) if(dis(city[i],city[j])<=mid) g.link(i+1,j+1); if(g.Dance(0)){R=mid-1;ans=mid; } else L=mid+1; } printf("Case #%d: %I64d\n",cc,ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/Opaser/p/4693184.html