首页 > 代码库 > HDU 5046 Airport(dlx)

HDU 5046 Airport(dlx)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5046

题意:n个城市修建m个机场,使得每个城市到最近进场的最大值最小。

思路:二分+dlx搜索判定。

 

const int INF=1000000005;const int N=4444;int m;struct node{	int L[N],R[N],D[N],U[N],e;	int col[N];	int H[N],num[N];	int visit[N],KK;	void init(int n)	{		KK=0;		int i;		for(i=0;i<=n;i++)		{			if(i==n) L[i]=0;			else L[i]=i+1;			if(i==0) R[i]=n;			else R[i]=i-1;			num[i]=0;			H[i]=-1;			D[i]=U[i]=i;		}		e=n+1;	}	void add(int r,int c)	{		U[e]=c;		D[e]=D[c];		U[D[c]]=e;		D[c]=e;		if(H[r]<0) H[r]=L[e]=R[e]=e;		else		{			L[e]=L[H[r]];			R[e]=H[r];			R[L[H[r]]]=e;			L[H[r]]=e;		}		num[c]++;		col[e]=c;		e++;	}	void remove(int c)	{		int i;		for(i=D[c];i!=c;i=D[i])		{			R[L[i]]=R[i];			L[R[i]]=L[i];		}	}	void resume(int c)	{		int i;		for(i=U[c];i!=c;i=U[i])		{			L[R[i]]=R[L[i]]=i;		}	}	int astar()	{		KK++;		int ans=0,i,j,k;		for(i=L[0];i!=0;i=L[i]) if(KK!=visit[i])		{			visit[i]=KK;			ans++;			for(j=D[i];j!=i;j=D[j]) for(k=L[j];k!=j;k=L[k])			{				visit[col[k]]=KK;			}		}		return ans;	}	int DFS(int cnt)	{		if(L[0]==0) return 1;		if(cnt+astar()>m) return 0;		int tmp=INF,c,i;		for(i=L[0];i!=0;i=L[i]) if(num[col[i]]<tmp)		{			tmp=num[col[i]];			c=i;		}		for(i=D[c];i!=c;i=D[i])		{			remove(i);			int j;			for(j=L[i];j!=i;j=L[j]) remove(j);			if(DFS(cnt+1)) return 1;			for(j=R[i];j!=i;j=R[j]) resume(j);			resume(i);		}		return 0;	}}A;int a[66][2];i64 dis[66][66];int n;i64 d[4444];inline i64 dist(int i,int j){	return ((i64)abs(a[i][0]-a[j][0]))+abs(a[i][1]-a[j][1]);}int ok(i64 M){	A.init(n);	int i,j;	for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(dis[i][j]<=M)	{		A.add(i,j);	}	return A.DFS(0);}i64 cal(){	int num=0;	int i,j;	for(i=1;i<=n;i++) for(j=1;j<=n;j++) dis[i][j]=dist(i,j),d[num++]=dis[i][j];	sort(d,d+num);	int M=unique(d,d+num)-d;	int low=0,high=M-1;	i64 ans=0;	while(low<=high)	{		int mid=(low+high)>>1;		if(ok(d[mid])) ans=d[mid],high=mid-1;		else low=mid+1;	}	return ans;}int main(){	int num=0;	int T=getInt();	while(T--)	{		n=getInt();		m=getInt();		int i;		for(i=1;i<=n;i++) scanf("%d%d",&a[i][0],&a[i][1]);		printf("Case #%d: ",++num);		cout<<cal()<<endl;	}}

 

HDU 5046 Airport(dlx)