观前注意/知识普及:2-CNF指每个或操作有2项;2-SAT指每个项有2个取值。因为3-CNF及以上是NPC,故经常省略2-CNF。
关于2-CNF-2-SAT的写法 下面代码无法通过
struct TwoSAT{
int n,mark[maxn<<1],S[maxn<<1],c;
vector<int>G[maxn<<1];
void init(int nn){
n=nn;
for(int i=0;i<(n<<1);i++)
{G[i].clear();mark[i]=false;}
}
void AddEdge(int x,int xc,int y,int yc){
x=x*2+xc;y=y*2+yc;
G[x].push_back(y);
}
bool dfs(int u){
if(mark[u^1])return false;
if(mark[u])return true;
mark[S[++c]=u]=true;
for(int v:G[u])
if(!dfs(v))return false;
return true;
}
bool solve(){
for(int i=0;i<n;i++)
if(!mark[i*2]&&!mark[i*2+1]){
c=0;
if(dfs(i*2))continue;
while(c)mark[S[c--]]=false;
if(!dfs(i*2+1))return false;
}
return true;
}
}solver;
Hack:强制令第一个变量为false,第2~n-1个变量若true则下个变量为true,若第n个变量为true则第一个变量为false,此种情况下时间复杂度为O(n2)