P4782 【模板】2-SAT

题目链接:P4782

 

题目大意:

给n个bool变量,以及m个条件,问n个变量如何取值使得条件成立。

 

参考代码:

 

 1 // 2-SAT
 2 // Tarjan缩点
 3 #include <iostream>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <queue>
 9 #include <vector>
10 #include <stack>
11 #define N 1000010<<1
12 #define ll long long
13 using namespace std;
14 bool vis[N];
15 int tp,id,indx,cnt,n,m,u,v,a,b,head[N],nxt[N],to[N],dfn[N],low[N],col[N],s[N];
16 inline int read()
17 {
18     int x = 0, y = 1; char c = getchar();
19     while(c < '0' || c > '9') {if(c == '-') y = -1; c = getchar();}
20     while(c >= '0' && c <= '9') x = x*10+c-'0', c = getchar();
21     return x*y;
22 }
23 void add(int u, int v)
24 {
25     nxt[++cnt] = head[u];
26     head[u] = cnt;
27     to[cnt] = v;
28 }
29 void tarjan(int u) // 缩点
30 {
31     dfn[u] = low[u] = ++id; s[++tp] = u; vis[u] = true;
32     for(int i = head[u]; ~i; i = nxt[i])
33     {
34         int v = to[i];
35         if(!dfn[v])
36         {
37             tarjan(v);
38             low[u] = min(low[v],low[u]);
39         } else if(vis[v]) low[u] = min(low[v],low[u]);
40     }
41     if(dfn[u] == low[u])
42     {
43         vis[u] = false;
44         col[u] = ++indx;
45         while(s[tp] != u)
46         {
47             vis[s[tp]] = false;
48             col[s[tp]] = indx;
49             tp--;
50         }
51         tp--;
52     }
53 }
54 int main()
55 {
56     cnt = -1; n = read(); m = read();
57     memset(head,-1,sizeof(head));
58     for(int i = 0; i < m; i++)
59     {
60         u = read(); a = read(); v = read(); b = read();
61         add(u+n*(a&1),v+n*(b^1)); // a为真,则a+n为假,a与b矛盾,则取a则取b+n,取b则取a+n
62         add(v+n*(b&1),u+n*(a^1));
63     }
64     for(int i = 1; i <= (n<<1); i++)
65         if(!dfn[i])
66             tarjan(i);
67     for(int i = 1; i <= n; i++)
68     {
69         if(col[i] == col[i+n]) // 矛盾
70         {
71             printf("IMPOSSIBLE");
72             return 0;
73         }
74     }
75     printf("POSSIBLE\n");
76     for(int i = 1; i <= n; i++)
77     {
78         printf("%d ",col[i]<col[i+n]); // 因为栈,col里存的是拓扑逆序
79     }
80     printf("\n");
81     return 0;
82 }

 

posted @ 2020-11-23 20:22  不敢说的梦  阅读(122)  评论(0)    收藏  举报