题目链接:点击打开链接
思路:2-SAT基础题, 关键是要理解好模板的含义,然后重点在建图。
在2-SAT中, 问题的关键是处理矛盾关系, 找到一个可行的解满足所有关系。 然后我们建图的时候, 连接一条有向边, 这条有向边可以理解成导出关系, a -> b。 那么我们可以由此来建立关系运算符, 以AND操作为例, 如果AND操作为真, 那么!a -> a, !b -> b, 代表, 如果a为假, 这是不行的, 必须改成a为真。
细节参见代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<queue> #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) using namespace std; typedef long long ll; typedef long double ld; const ld eps = 1e-9, PI = 3.1415926535897932384626433832795; const int mod = 1000000000 + 7; const int INF = 0x3f3f3f3f; // & 0x7FFFFFFF const int seed = 131; const ll INF64 = ll(1e18); const int maxn = 100; int T,n,m; struct two_SAT { int n; vector<int> G[maxn * 2]; bool mark[maxn*2]; int S[maxn*2], c; bool dfs(int x) { if(mark[x ^ 1]) return false; if(mark[x]) return true; mark[x] = true; S[c++] = x; int len = G[x].size(); for(int i = 0; i < len; i++) { if(!dfs(G[x][i])) return false; } return true; } inline void init(int n) { this -> n = n; for(int i = 0; i < n*2; i++) G[i].clear(); memset(mark, false, sizeof(mark)); } inline void add_clause(int x, int xval, int y, int yval) { x = x * 2 + xval; y = y * 2 + yval; G[x].push_back(y); } inline bool solve() { for(int i = 0; i < n*2; i += 2) { if(!mark[i] && !mark[i+1]) { c = 0; if(!dfs(i)) { while(c > 0) mark[S[--c]] = false; if(!dfs(i+1)) return false; } } } return true; } }g; int a, b, c; char s[100]; // 该算法结点从0开始标号 int main() { while(~scanf("%d%d",&n,&m)) { g.init(n); for(int i = 0; i < m; i++) { scanf("%d%d%d%s",&a, &b, &c, s); if(s[0] == 'A') { if(c) { g.add_clause(a, 0, a, 1); g.add_clause(b, 0, b, 1); } else { g.add_clause(a, 1, b, 0); g.add_clause(b, 1, a, 0); } } else if(s[0] == 'O') { if(c) { g.add_clause(a, 0, b, 1); g.add_clause(b, 0, a, 1); } else { g.add_clause(a, 1, a, 0); g.add_clause(b, 1, b, 0); } } else { if(c) { g.add_clause(a, 0, b, 1); g.add_clause(a, 1, b, 0); g.add_clause(b, 0, a, 1); g.add_clause(b, 1, a, 0); } else { g.add_clause(a, 0, b, 0); g.add_clause(a, 1, b, 1); g.add_clause(b, 0, a, 0); g.add_clause(b, 1, a, 1); } } } if(g.solve()) printf("YES\n"); else printf("NO\n"); } return 0; }