2-sat模版(完整版)
以前做过的题目,现在整理了一下,去掉了和具体题目相关的细节,并加上了一些注释,方便使用吧。
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int N = 1010; int n; //原图中共有2*n个相对的节点。 int ct, depth, top, index[N<<1], d[N<<1], low[N<<1], stack[N<<1]; bool instack[N<<1], map[N<<1][N<<1], g[N<<1][N<<1]; int tot, et[N<<1], color[N<<1], op[N<<1]; bool visit[N<<1]; void initData() { //初始化数据,根据题意建图,建好的初始图为map ........ } void dfs(int u) { //tarjan求强连通分量,缩点 int i, x; d[u] = low[u] = depth++; stack[++top] = u; instack[u] =true; for(i = 0; i < n+n; i++) if(map[u][i]) { if(d[i] == -1) { dfs(i); low[u] = min(low[u], low[i]); } else { if(instack[i]) low[u] = min(low[u], d[i]); } } if(low[u] == d[u]) { ct++; while(top) { x = stack[top--]; instack[x] = false; index[x] = ct; if(x == u) break; } } } void buildNewGraph() { //根据缩点建立新图 int i, j; memset(g, false, sizeof(g)); for(i = 0; i < n+n; i++) for(j = 0; j < n+n; j++) if(map[i][j]) g[index[i]][index[j]] = true; for(i = 1; i <= ct; i++) for(j = i+1; j <= ct; j++) swap(g[i][j], g[j][i]); //将新图中的边反向 for(i = 0; i < n; i++) { //根据原图的矛盾节点确定新图的矛盾节点 op[index[i]] = index[i+n]; op[index[i+n]] = index[i]; } } void transDfs(int u) { int i; visit[u] =true; for(i = 1; i <= ct; i++) if(!visit[i] && g[u][i]) transDfs(i); et[++tot] = u; } void colorDfs(int u) { int i; color[u] = 0; for(i = 1; i <= ct; i++) if(color[i]==-1 && g[u][i]) colorDfs(i); } void generateAns() { int i; memset(visit, false, sizeof(visit)); tot = 0; //拓扑排序 for(i = 1; i <= ct; i++) if(!visit[i]) transDfs(i); memset(color, -1, sizeof(color)); for(i = ct; i > 0; i--) if(color[et[i]] == -1) { color[et[i]] = 1; //选择第一个未着色的顶点x, 把x染成红色1, 并把与之矛盾的节点y及其所有子孙节点染成蓝色0。 colorDfs(op[et[i]]); } } void solve() { int i; depth = top = ct =0; memset(d, -1, sizeof(d)); memset(instack, false, sizeof(instack)); for(i = 0; i < n+n; i++) if(d[i] == -1) dfs(i); for(i = 0; i < n; i++) if(index[i] == index[i+n]) break; if(i < n) printf("NO\n"); else { printf("YES\n"); buildNewGraph(); generateAns(); //printAns(); } } int main() { initData(); solve(); return 0; }