2-SAT水题,还wa了好几次,可见本菜更水。。。课件上都有讲解。。。
渣代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <stack>
using namespace std;
const int N = 2012;
const int M = 1000000;
struct node {
int to;
int next;
} g[M];
int head[N], scc[N];
int dfn[N], low[N];
int t, ind, cnt;
bool vis[N];
stack<int> s;
void init() {
for(int i = 0; i < N; i++) {
head[i] = scc[i] = dfn[i] = low[i] = vis[i] = 0;
}
t = 1; ind = cnt = 0;
}
void add(int u, int v) {
g[t].to = v; g[t].next = head[u]; head[u] = t++;
}
void tarjan(int u) {
int v, i;
dfn[u] = low[u] = ++ind;
s.push(u); vis[u] = true;
for(i = head[u]; i; i = g[i].next) {
v = g[i].to;
if(!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
} else if(vis[v]) {
low[u] = min(low[u], dfn[v]);
}
}
if(dfn[u] == low[u]) {
cnt++;
do {
v = s.top(); s.pop();
scc[v] = cnt;
vis[v] = false;
} while(v != u);
}
}
int main() {
//freopen("data.in", "r", stdin);
int n, m, i;
int a, b, c, d;
bool flag;
while(~scanf("%d%d", &n, &m)) {
init();
while(m--) {
scanf("%d%d%d%d", &a, &b, &c, &d);
if(c == 0) {
if(d == 0) {add(a<<1, (b<<1)+1); add(b<<1, (a<<1) + 1);}
else {add((a<<1), (b<<1)); add((b<<1)+1, (a<<1)+1);}
} else {
if(d == 0) {add((a<<1) + 1, (b<<1) + 1); add(b<<1, a<<1);}
else {add((a<<1)+1, b<<1), add((b<<1)+1, a<<1);}
}
}
for(i = 0; i < n*2; i++) {
if(!dfn[i]) tarjan(i);
}
for(flag = true, i = 0; i < n; i++) {
if(scc[i*2] == scc[i*2+1]) {
flag = false;
cout << "NO" << endl;
break;
}
}
if(flag) cout << "YES" << endl;
}
return 0;
}