UVALive 3211 : Now or later 【2-SAT】

题目链接

题意及题解参见lrj训练指南

#include<bits/stdc++.h>
using namespace std;

const int maxn=4e3+5;

struct TwoSAT
{
    int n;
    vector<int> adj[maxn*2];
    bool mark[maxn*2];
    int S[maxn*2],c;
    void init(int n)
    {
        this->n=n;
        for(int i=0;i<n*2;i++) adj[i].clear();
        memset(mark,0,sizeof(mark));
    }
    void add_clause(int x,int xval,int y,int yval)
    {
        x=x*2+xval;
        y=y*2+yval;
        adj[x^1].push_back(y);
        adj[y^1].push_back(x);
    }
    bool dfs(int x)
    {
        if(mark[x^1]) return false;
        if(mark[x]) return true;
        mark[x]=true;
        S[c++]=x;
        for(int v:adj[x])
            if(!dfs(v)) return false;
        return true;
    }
    bool ok()
    {
        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;
    }
};
//=============================================================

TwoSAT solver;
int n,T[maxn][2];

bool test(int diff)
{
    solver.init(n);
    for(int i=0;i<n;i++) for(int a=0;a<2;a++)
        for(int j=i+1;j<n;j++) for(int b=0;b<2;b++)
            if(abs(T[i][a]-T[j][b])<diff) solver.add_clause(i,a^1,j,b^1);
    return solver.ok();
}

int main()
{
    while(scanf("%d",&n)>0&&n)
    {
        int L=0,R=0;
        for(int i=0;i<n;i++) for(int a=0;a<2;a++)
        {
            scanf("%d",&T[i][a]);
            R=max(R,T[i][a]);
        }
        while(R-L>1)
        {
            int M=(L+R)/2;
            if(test(M)) L=M;
            else R=M;
        }
        printf("%d\n",L);
    }
}

 

posted @ 2017-10-16 13:42 wy_2016 阅读(...) 评论(...) 编辑 收藏