uva1146 2-SAT问题

题意大白书

二分答案,然后对于每个可能的答案,跑一遍2-SAT就好了。

#include <iostream>
#include <string.h>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn=2000+10;
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 inti(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;
   }
}solver;
int n,T[maxn][2];
bool test(int diff){
    solver.inti(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.solve();
}
int main()
{
      while(scanf("%d",&n)==1 && 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(L<R){
             int M = L + ( R - L +1)/2;
             if(test(M)) L=M; else R=M-1;
          }
          printf("%d\n",L);
      }
    return 0;
}
View Code

 

posted @ 2015-03-06 20:41  来自大山深处的菜鸟  阅读(124)  评论(0编辑  收藏  举报