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 }

浙公网安备 33010602011771号