h.
題目條件轉換為,三個值不能有兩個同時為負數。
把 x,-x 看作 x,\lnot x,條件就變成了 (x \land y) \lor (x \land z) \lor (y \land z)。
這個形式顯然是 2-sat,程式碼很好寫。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e6 + 7;
int v[4][N];
vector<int> g[N];
int n;
void add(int a, int b) {
int k1, k2;
if(a > 0) k1 = 1;
else k1 = 0;
if(b > 0) k2 = 1;
else k2 = 0;
a = abs(a);
b = abs(b);
if(k1 && k2){
g[a + n].push_back(b);
g[b + n].push_back(a);
}
else if(!k1 && k2){
g[a].push_back(b);
g[b + n].push_back(a + n);
}
else if(k1 && !k2){
g[a + n].push_back(b + n);
g[b].push_back(a);
}
else if(!k1 && !k2){
g[a].push_back(b + n);
g[b].push_back(a + n);
}
}
int col[N], scc[N], dfn[N], low[N], vis[N];
int scccnt, dfncnt, stk[N], top;
void tarjan(int u) {
low[u] = dfn[u] = ++ dfncnt;
stk[++ top] = u;
vis[u] = 1;
for(auto v : g[u]) {
if(!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if(vis[