码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5046 Airport(dlx)

时间:2014-09-27 23:32:50      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:blog   http   ar   for   sp   div   on   c   log   

题目链接: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)

标签:blog   http   ar   for   sp   div   on   c   log   

原文地址:http://www.cnblogs.com/jianglangcaijin/p/3997217.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!