书上2-sat的例题,受教了~
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=3001;
int n;
int t[maxn][2];
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;
}
}solver;
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.solve();
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
int r=0,l=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 mid=(l+r+1)>>1;
if(test(mid))
l=mid;
else
r=mid-1;
}
printf("%d\n",l);
}
return 0;
}