TwoSAT模版(LRJ)

来源:互联网 发布:腾讯代理吃鸡会优化吗 编辑:程序博客网 时间:2024/05/22 17:55
#include<cstdio>#include<cstring>#include<queue>#include<vector>#include<algorithm>using namespace std;const int maxn = 100;struct TwoSAT {  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;    for (int i = 0; i < G[x].size(); i++)      if (!dfs(G[x][i])) return false;    return true;  }  void init(int n) {    this->n = n;    for (int i = 0; i < n*2; i++) G[i].clear();    memset(mark, 0, sizeof(mark));  }  // x = xval or y = yval  void add_clause(int x, int xval, int y, int yval) {    x = x * 2 + xval;    y = y * 2 + yval;    G[x^1].push_back(y);    G[y^1].push_back(x);  }  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;  }};TwoSAT solver;

模版中容易敲错的地方,一定要想清楚是2*n还是n,n++还是n+=2。对于有些mark值已经定下来的题目,在solve前需要改动,先判断mark[i]和mark[i+1]是否都为1。注意模板中点的下标是从0开始的。
原创粉丝点击