HDU 4421 Bit Magic[2_sat]
题意:判断矩阵是否符合条件:
思路:建图方式
对于&操作,
if(c = 1)
当a为1时b必须为1,当b为1时a必须为1;
当a为0时a必须为1,当b为0时b必须为1,否则不可能为1
else {
当a为1时b必须为0,当b为1时a必须为0;
当a为0时一定为0没有矛盾产生,当b为0时一定为0没有矛盾产生;
}
对于|操作
if(c = 0)
当a为0时b必须为0,当b为0时a必须为0;
当a为1时a必须为0,当b为1时b必须为0,否则不可能为0
else {
当a为0时b必须为1,当b为0时a必须为1;
当a为1时一定为1没有矛盾产生,当b为1时一定为1没有矛盾产生;
}
对于^操作
if(c = 0)
当a为0时b必须为0,当b为0时a必须为0;
当a为1时b必须为1,当b为1时a必须为1;
else {
当a为0时b必须为1,当b为0时a必须为1;
当a为1时b为0,当b为1时a为0;
}
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define maxn 1005 #define clr(x) memset(x,0,sizeof(x)) struct node { int to, next; }e[1000000]; int tot; int head[maxn]; void add(int s, int t) { e[tot].to = t; e[tot].next = head[s]; head[s] = tot++; } int top, sn, ti; int dfn[maxn]; int low[maxn]; int sta[maxn]; int ins[maxn]; int col[maxn]; void tarjan(int u) { dfn[u] = low[u] = ++ti; sta[++top] = u; ins[u] =1; int i, k; for (i=head[u]; i; i=e[i].next) { k = e[i].to; if(dfn[k] == 0) { tarjan(k); low[u] = min(low[u],low[k]); } else if(ins[k]) low[u] = min(low[u],dfn[k]); } if(dfn[u] == low[u]) { sn++; do { k = sta[top--]; ins[k] = 0; col[k] = sn; }while(k != u); } } void init() { tot = 1; top = sn = ti = 0; clr(dfn); clr(head); clr(col); clr(ins); } int map[505][505]; int main() { int i, j, k, n, sta; bool flag; while(scanf("%d",&n) != EOF) { flag = true; for(i=0; i<n; i++) for(j=0; j<n; j++) scanf("%d",&map[i][j]); for(i = 0; i<n; i++) if(map[i][i] != 0) { flag = false; goto loop; } for(k=0; k<32; k++) { init(); for(i=0; i<n; i++) for(j=0; j<n; j++) { if(i == j) continue; sta = map[i][j]&(1<<k); if(i%2==1 && j%2==1) { if(sta) { add(i, j+n); add(j, i+n); } else { add(i+n, i); add(j+n, j); add(i, j); add(j, i); } } else if(i%2==0 && j%2==0) { if(sta) { add(i, i+n); add(j, j+n); add(i+n, j+n); add(j+n, i+n); } else { add(i+n, j); add(j+n, i); } } else { if(sta) { add(i, j+n); add(j, i+n); add(i+n, j); add(j+n, i); } else { add(i, j); add(j, i); add(i+n, j+n); add(j+n, i+n); } } } for(i=0; i<2*n; i++) if(dfn[i] == 0) tarjan(i); for(i=0; i<n; i++) if(col[i] == col[i+n]) { flag = false; goto loop; } } loop: printf("%s\n",flag ? "YES":"NO"); } return 0; }