LA 3211(p325)----Now or later

#include<bits/stdc++.h>
#define debu
using namespace std;
const int maxn=2*1e3+50;
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<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,0,sizeof(mark));
    }
    void add_clause(int x,int xval,int y,int yval)
    {
        x=x*2+xval;
        y=y*2+yval;
        G[x^1].push_back(y);
        G[y^1].push_back(x);
    }
    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;
    }
};
int n,maxt;
TwoSAT ans;
int g[maxn][2];
int check(int val)
{
    ans.init(n);
    for(int i=0; i<n; i++)
        for(int j=i+1; j<n; j++)
        {
            if(abs(g[i][0]-g[j][0])<val) ans.add_clause(i,0,j,0);
            if(abs(g[i][0]-g[j][1])<val) ans.add_clause(i,0,j,1);
            if(abs(g[i][1]-g[j][0])<val) ans.add_clause(i,1,j,0);
            if(abs(g[i][1]-g[j][1])<val) ans.add_clause(i,1,j,1);
        }
    return ans.solve();
}
int solve()
{
    int l=0,r=maxt,mid;
    while(l<=r)
    {
        mid=(l+r)>>1;
       // cout<<l<<" "<<r<<endl;
        if(check(mid)) l=mid+1;
        else r=mid-1;
    }
    return r;
}
int main()
{
#ifdef debug
    freopen("in.in","r",stdin);
#endif // debug
    while(scanf("%d",&n)!=EOF)
    {
        maxt=0;
        memset(g,0,sizeof(g));
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<2; j++)
            {
                scanf("%d",&g[i][j]);
                maxt=max(maxt,g[i][j]);
            }
        }
        printf("%d\n",solve());
    }
    return 0;
}

题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1212

题解:二分时间间隔val,对于每对不满足条件(例如abs(early[i]-later[j])<val,x[i]==1表示i选择早到,x[i]==0表示i选择晚到,则x[i]==1与x[j]==0不能同时选择(即2-SAT中的限制条件)),所以若2-SAT有解,则说明当前val可行,二分求最大值即可。

你可能感兴趣的:(LA 3211(p325)----Now or later)