现在的位置: 首页 > 综合 > 正文

LA3211

2014年10月03日 ⁄ 综合 ⁄ 共 1263字 ⁄ 字号 评论关闭

“相邻两个着陆时间间隔的最小值应尽量大”很容易让人想到二分答案。

因此我们可以二分这个尽可能大的最小值,然后每次建立一个2-SAT的模型。

即满足相邻的四个时间差绝对值如果小于我们枚举的值就连边。

(现在才发现其实2-SAT并不难写……lrj的代码也很好理解)

#include<bits/stdc++.h>
using namespace std;
const int maxn=2000+10;
int n,e[maxn],l[maxn];
vector<int> G[maxn*2];
bool vis[maxn*2];
int S[maxn*2],cnt;
void init(int n)
{
	for(int i=0;i<n*2;i++)
		G[i].clear();
	memset(vis,false,sizeof vis);
}
void addedge(int x,bool vx,int y,bool vy)
{
	int tx=x*2+vx,ty=y*2+vy;
	G[tx^1].push_back(ty);
	G[ty^1].push_back(tx);
}
bool DFS(int u)
{
	if(vis[u^1])
		return false;
	if(vis[u])
		return true;
	vis[S[cnt++]=u]=true;
	for(int i=0,size=G[u].size();i<size;i++)
		if(!DFS(G[u][i]))
			return false;
	return true;
}
bool solve()
{
	for(int i=0;i<n*2;i+=2)
		if(!vis[i]&&!vis[i+1])
		{
			cnt=0;
			if(!DFS(i))
			{
				while(cnt>0)
					vis[S[--cnt]]=false;
				if(!DFS(i+1))
					return false;
			}
		}
	return true;
}
bool ok(int M)
{
	init(n);
	for(int i=0;i<n;i++)
		for(int j=i+1;j<n;j++)
		{
			if(abs(e[i]-e[j])<M)
				addedge(i,true,j,true);
			if(abs(e[i]-l[j])<M)
				addedge(i,true,j,false);
			if(abs(l[i]-e[j])<M)
				addedge(i,false,j,true);
			if(abs(l[i]-l[j])<M)
				addedge(i,false,j,false);
		}
	return solve();
}
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		int L=0,R=0;
		for(int i=0;i<n;i++)
		{
			scanf("%d%d",&e[i],&l[i]);
			R=max(R,max(e[i],l[i]));
		}
		while(L<R)
		{
			int M=L+(R-L+1)/2;
			if(ok(M))
				L=M;
			else R=M-1;
		}
		printf("%d\n",L);
	}
	return 0;
}
/*
10
44 156
153 182
48 109
160 201
55 186
54 207
55 165
17 58
132 160
87 197
*/
【上篇】
【下篇】

抱歉!评论已关闭.