LA 3211 Now or Later

来源:互联网 发布:阿里云备份如何恢复 编辑:程序博客网 时间:2024/05/17 23:49

最小值最大问题:二分+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;}


原创粉丝点击