2-sat 入门题
《由对称性解2-SAT问题》
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <stack> using namespace std; const int N = 2010; vector<int> vec[N]; int n, m, id, cnt; int dfn[N], vis[N], low[N], belong[N]; stack<int> s; void init(){ memset(vis,0,sizeof(vis)); memset(dfn,-1,sizeof(dfn)); memset(low,-1,sizeof(low)); memset(belong,-1,sizeof(belong)); id = cnt = 0; while(!s.empty())s.pop(); for(int i = 0; i < 2*n; i++)vec[i].clear(); } void tarjan(int u){ dfn[u] = low[u] = id++; vis[u] = 1; int sz = vec[u].size(); s.push(u); for(int i = 0; i < sz; i++){ int v = vec[u][i]; if(dfn[v] == -1){ tarjan(v); low[u] = min(low[u], low[v]); } else if(vis[v] == 1){ low[u] = min(low[u], dfn[v]); } } if(low[u] == dfn[u]){ cnt++; while(!s.empty()){ int temp = s.top(); s.pop(); vis[temp]=0; belong[temp]=cnt; if(temp == u)break; } } } int main(){ int a,b,c,d; while(~scanf("%d%d", &n, &m)){ init(); for(int i = 0; i < m; i++){ scanf("%d%d%d%d", &a, &b, &c, &d); vec[2*a+c].push_back(2*b+1-d); vec[2*b+d].push_back(2*a+1-c); } for(int i = 0; i < 2*n; i++){ if(dfn[i] == -1)tarjan(i); } bool flag = true; for(int i = 0; i < n; i++){ if( belong[2*i] == belong[2*i+1] ){ flag=false; break; } } puts(flag?"YES":"NO"); } return 0; }