- 间隔最小值尽量大,二分时间t。
- 一架飞机的早与晚看成图上两个点i与!i,验证当前mid值,若两点i,j间的间隔<t,则连i->!j,j->!i,表示选了i不能选j,选了j不能选i.
- 注意二分不要写错
#include <iostream>#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
int n,a[4020],cnt,last[4020],c,s[4005];
bool mark[4020];
struct edge{
int v,next;
}e[19000050];
inline void add(int u,int v)
{
e[++cnt].v=v^1;
e[cnt].next=last[u];
last[u]=cnt;
e[++cnt].v=u^1;
e[cnt].next=last[v];
last[v]=cnt;
}
bool dfs(int x)
{
if(mark[x^1]) return false;
if(mark[x]) return true;
mark[x]=1;
s[c++]=x;
for(int i=last[x];i;i=e[i].next)
if(!dfs(e[i].v)) return false;
return true;
}
bool solve()
{
for(int i=0;i<2*n;i+=2)
{
if(!mark[i]&&!mark[i^1])
{
if(!dfs(i))
{
while(c>0) mark[s[--c]]=0;
if(!dfs(i^1)) return false;
}
}
}
return true;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
int l=0,r=0;
for(int i=0;i<n;i++)
{
scanf("%d%d",&a[2*i],&a[2*i+1]);
r=max(r,max(a[2*i],a[2*i+1]));
}
int mid=(l+r)/2;
while(l<=r)
{
for(int i=0;i<2*n;i++)
for(int j=i+1;j<2*n;j++)
if(abs(a[i]-a[j])<mid)
add(i,j);
if(solve())
l=mid+1;
else
r=mid-1;
mid=(l+r)/2;
memset(mark,0,sizeof(mark));
memset(last,0,sizeof(last));
memset(s,0,sizeof(s));
for(int i=1;i<=cnt;i++)
e[i].next=e[i].v=0;
cnt=c=0;
}
cout<<l-1<<endl;
}
return 0;
}