题意:n 架飞机,每架飞机的降落时间有两个选择,一个为早点降落,另一个为晚点降落,求两架飞机降落时间差的最小值的最大值(就是使得所有飞机降落的时间差的最小值尽量大)
思路:对时间进行二分,然后进行2-SAT的判断
#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 2005;
const int VN = maxn * 2;
const int EN = maxn * maxn * 4;
int n, m;
int t[maxn][2];
struct Graph
{
int cnt, head[VN];
struct
{
int v, next;
} E[EN];
void init()
{
cnt = 0;
memset(head, -1, sizeof(head));
}
void add(int u, int v)
{
E[cnt].v = v;
E[cnt].next = head[u];
head[u] = cnt++;
}
} g;
struct Two_Sat
{
bool check()
{
scc();
for(int i = 0; i < n; ++i)
if(col[i * 2] == col[i * 2 + 1])
return false;
return true;
}
void tarjan(const int u)
{
int v;
low[u] = dfn[u] = ++idx;
vis[u] = true;
sta[top++] = u;
for(int e = g.head[u]; e != -1; e = g.E[e].next)
{
v = g.E[e].v;
if(dfn[v] == -1)
{
tarjan(v);
low[u] = min(low[u], low[v]);
}
else
if(vis[v])
low[u] = min(low[u], dfn[v]);
}
if(dfn[u] == low[u])
{
++sn;
do
{
v = sta[--top];
vis[v] = false;
col[v] = sn;
}
while(u != v);
}
}
void scc()
{
idx = top = sn = 0;
memset(vis, 0, sizeof(vis));
memset(dfn, -1, sizeof(dfn));
for(int i = 0; i < 2 * n; ++i)
if(dfn[i] == -1)
tarjan(i);
}
int idx, top, sn;
int sta[VN], low[VN], dfn[VN], col[VN];
bool vis[VN];
} sat;
void build(int Min)
{
g.init();
for(int i = 0; i < n; ++i)
{
for(int j = i + 1; j < n; ++j)
{
int ta1 = t[i][0], ta2 = t[i][1];
int tb1 = t[j][0], tb2 = t[j][1];
if(abs(ta1 - tb1) < Min)
{
g.add(i * 2, j * 2 + 1);
g.add(j * 2, i * 2 + 1);
}
if(abs(ta1 - tb2) < Min)
{
g.add(i * 2, j * 2);
g.add(j * 2 + 1, i * 2 + 1);
}
if(abs(ta2 - tb1) < Min)
{
g.add(i * 2 + 1, j * 2 + 1);
g.add(j * 2, i * 2);
}
if(abs(ta2 - tb2) < Min)
{
g.add(i * 2 + 1, j * 2);
g.add(j * 2 + 1, i * 2);
}
}
}
}
int main()
{
while(~scanf("%d", &n))
{
int l = 0, r = 0, mid, ans = -1;
for(int i = 0; i < n; ++i)
{
scanf("%d%d", &t[i][0], &t[i][1]);
r = max(t[i][0], max(t[i][1], r));
}
while(l < r)
{
mid = (l + r) >> 1;
build(mid);
if(sat.check())
{
ans = mid;
l = mid + 1;
}
else
r = mid;
}
printf("%d\n", ans);
}
return 0;
}