2-SAT (two-statisfiability) algorithm study notes

$ 2-SAT problem refers to certain restrictions for obtaining a set of feasible solutions of the problem.

Consider for a range of $ n-$ $ $ {0,1} variables $ x_1, x_2, ..., x_n $ satisfy several limitations:

若 $x_i = p$ 则 $x_j = q ( i,j\in[1,n],p,q \in \{0,1\})$

We consider for each variable $ $ x_i open a range $ x_ {i, 0}, x_ {i, 1} $ $ I $ denotes the value of variable $ 0 / $ 1 point.

Then consider each group proposition, if the $ x_i = p $ $ x_j = q, i, j \ in [1, n], p, q \ in \ {0,1 \} $,

First, the $ x_ {i, p} $ and $ x_ {j, q} $ two points even a unidirectional edge.

And because of this proposition is very special, just the size range of 2, its inverse proposition also no limit (can obvious evidence to the contrary).

Then put $ x_ {j, 1-q} $ and $ x_ {i, 1-p} $ even a unidirectional edge.

 

Then run for the above FIG tarjan identify SCC, if $ x_ {i, 0} $ and $ x_ {i, 1} $ communicating in the same block,

Description The following proposition is true: " If the $ x_i = 0 $ then $ x_i = 1 $", "$ x_i = 1 $ if the $ x_i = 0 $" So the answer is no solution at this time.

 

How to construct a set of solutions of it, due to the characteristics of tarjan of dfs,

$ $ C_i provided tarjan represented by the communication block number determined algorithm (which itself is an inverse sequence topology).

$ Val_i = c_ {x_ {i, 0}}> c_ {x_ {i, 1}} $ to construct $ val_i, i \ in [1, n] $ a solution of the combination method.

P4782 [template] 2-SAT problem

Set variable $ x_i \ in \ {0,1 \} $, give some set of relationships: $ x_i = p $ or $ x_j = q $ 

If $ x_i, (i \ in [1, n]) $ solvable, to output "POSIBLE" Method for Solving then outputs a combination thereof.

If $ x_i, (i \ in [1, n]) $ no solution, then the output "IMPOSIBLE" can.

To 100% of the data $ n, m \ leq 10 ^ 6 $

Sol: 

as x_i $ $ $ p $ or $ x_j is $ $ $ can be split into Q $ 2 \ times 2 $ logical relationship.
If $ $ x_i is $ 1-p $, $ x_j as the $ $ q $, $ x_j as if $ $ 1-q $, the $ x_i is $ p $ $

If $ x_j $ is a $ 1-q $, the $ x_i $ of $ P $, if $ x_i $ is a $ 1-p, $ the $ x_j $ of $ Q $
implementing aspects simply: $ [1, N] $ element of the original $ 0 $ domain, $ [N + 1,2N] $ $ 1 to $ element original domain.

# include <bits/stdc++.h>
using namespace std;
const int N=2e6+10,M=4e6+10;
struct rec{ int pre,to;}a[M];
stack<int>s;
bool ins[N];
int cnt,tot,n,m,head[N],c[N],dfn[N],low[N],val[N];
void adde(int u,int v)
{
    a[++tot].pre=head[u];
    a[tot].to=v;
    head[u]=tot;
}
void tarjan(int u)
{
    dfn[u]=low[u]=++dfn[0];
    s.push(u);ins[u]=1;
    for (int i=head[u];i;i=a[i].pre){
        int v=a[i].to;
        if (!dfn[v]) {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        } else if (ins[v]) low[u]=min(low[u],dfn[v]);
    }
    if (dfn[u]==low[u]) {
        cnt++; int v;
        do {
            v=s.top(); s.pop();
            ins[v]=0; c[v]=cnt;
        } while (u!=v);
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++) {
        int s,ps,t,pt; scanf("%d%d%d%d",&s,&ps,&t,&pt);
        adde(s+(1-ps)*n,t+pt*n); adde(t+(1-pt)*n,s+ps*n);
        adde(t+(1-pt)*n,s+ps*n); adde(s+(1-ps)*n,t+pt*n);
    }
    for (int i=1;i<=2*n;i++) if (!dfn[i]) tarjan(i);
    for (int i=1;i<=n;i++) if (c[i]==c[i+n]) {
        puts("IMPOSSIBLE"); return 0;
    }
    for (int i=1;i<=n;i++) val[i]=c[i]>c[n+i];
    puts("POSSIBLE");
    for (int i=1;i<=n;i++) printf("%d ",val[i]); puts("");
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/ljc20020730/p/11295659.html