最小值最大问题:二分+2SAT判定~~
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 2020;
const int INF = 0x3f3f3f3f;
inline int max(int a, int b)
{
return a > b ? a : b;
}
inline int min(int a, int b)
{
return a < b ? a : b;
}
struct TwoSAT
{
int n;
vector<int> G[MAXN*2];
bool mark[MAXN*2];
int S[MAXN*2], c;
bool dfs(int x)
{
if(mark[x^1]) return false;
if(mark[x]) return true;
mark[x] = true;
S[c++] = x;
for(int i = 0; i < static_cast<int>(G[x].size()); ++i)
if(!dfs(G[x][i]))
return false;
return true;
}
void Init(int n)
{
this->n = n;
for(int i = 0; i < n * 2; ++i)
G[i].clear();
memset(mark, false, sizeof(mark));
return ;
}
void add_clause(int x, int y)
{
G[x].push_back(y);
}
bool solve()
{
for(int i = 0; i < n * 2; i += 2)
{
if(!mark[i] && !mark[i+1])
{
c = 0;
if(!dfs(i))
{
while(c > 0) mark[S[--c]] = false;
if(!dfs(i+1)) return false;
}
}
}
return true;
}
}two_sat;
struct Node
{
int start_time, end_time;
Node() {}
Node(int s_t, int e_t) : start_time(s_t), end_time(e_t) {}
}node[MAXN];
int max_time, min_time;
void Create_Graph(int diff, int n)
{
two_sat.Init(n);
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < n; ++j)
{
if(i == j) continue;
if(abs(node[i].start_time - node[j].start_time) < diff)
{
two_sat.add_clause(2*i, 2*j+1);
}
if(abs(node[i].start_time - node[j].end_time) < diff)
{
two_sat.add_clause(2*i, 2*j);
}
if(abs(node[i].end_time - node[j].start_time) < diff)
{
two_sat.add_clause(2*i+1, 2*j+1);
}
if(abs(node[i].end_time - node[j].end_time) < diff)
{
two_sat.add_clause(2*i+1, 2*j);
}
}
}
return ;
}
int main()
{
//freopen("aa.in", "r", stdin);
int n;
while(scanf("%d", &n) != EOF)
{
max_time = -INF; min_time = INF;
for(int i = 0; i < n; ++i)
{
scanf("%d %d", &node[i].start_time, &node[i].end_time);
max_time = max(max_time, node[i].start_time);
min_time = min(min_time, node[i].start_time);
max_time = max(max_time, node[i].end_time);
min_time = min(min_time, node[i].end_time);
}
int low = 0, high = max_time - min_time, mid, ans = -INF;
while(low <= high)
{
mid = (low + high) / 2;
Create_Graph(mid, n);
if(two_sat.solve())
{
ans = max(ans, mid);
low = mid + 1;
}
else
{
high = mid - 1;
}
}
printf("%d\n", ans);
}
return 0;
}