有如下的代码:
现在给定b[N][N],求是否存在a[N]

void calculate(int a[N], int b[N][N]) {
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
if (i == j) b[i][j] = 0;
else if (i % 2 == 1 && j % 2 == 1) b[i][j] = a[i] | a[j];
else if (i % 2 == 0 && j % 2 == 0) b[i][j] = a[i] & a[j];
else b[i][j] = a[i] ^ a[j];
}
}
}

经典的2-sat题目。。跟POJ 3678差不多。。只不过是把每一位都拿出来比较了。。
用a’来代表该变量取0,a来代表该变量取1

1.a&b == 1 a’->a b’->b
2.a&b == 0 a->b’ b->a’
3.a|b == 1 a’->b b’->a
4.a|b == 0 a->a’ b->b’
5.a^b == 1 a<->b’ b<->a’
6.a^b == 0 a<->b a’<->b’

照此种方式建图。。。对于每一位。判断是否存在解。
若是想求任意解的话,也可以求出。
题目只要求判断是否存在。
代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 510;
struct Edge {
int to,next;
Edge(){}
Edge(int _to,int _next):to(_to),next(_next){}
}e[MAXN*MAXN*4+1100];
int head[MAXN*3],tot;
void init(){
memset(head,-1,sizeof(head)); tot=0;
}
void AddEdge(int u,int v){
e[tot]=Edge(v,head[u]);
head[u]=tot++;
//extern void print(int u,int v);
//print(u,v);
}
int dfn[MAXN*3],low[MAXN*3],sta[MAXN*3],bleg[MAXN*3];
int times,top;
void tarjan(int u){
dfn[u]=low[u]=++times;
sta[++top]=u;
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(!bleg[v])
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
++bleg[0];
do {
bleg[sta[top]]=bleg[0];
}while(sta[top--]!=u);
}
}
void print(int u,int v){
printf("%d%c-->%d%c\n",u>>1,(u&1)?'\'':' ',v>>1,(v&1)?'\'':' ');
}
int b[MAXN][MAXN],n;
int main()
{
while(~scanf("%d",&n)){
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&b[i][j]);
int flag=0;
for(int i=0;i<n;i++){
if(b[i][i]!=0)flag=1;
for(int j=i+1;j<n;j++){
if(b[i][j]!=b[j][i])flag=1;
}
}
for(int k=0;k<32&&!flag;k++){
init();
for(int i=0;i<n&&!flag;i++)
for(int j=0;j<n&&!flag;j++){
if(i==j)continue;
int t=(b[i][j]>>k)&1;
int aa=i+1,bb=j+1;
if(i%2==1&&j%2==1){
// |
if(t){
AddEdge(aa<<1|1,bb<<1);
AddEdge(bb<<1|1,aa<<1);
}
else {
AddEdge(aa<<1,aa<<1|1);
AddEdge(bb<<1,bb<<1|1);
}
}
else if(i%2==0&&j%2==0){
// &
if(t){
AddEdge(aa<<1|1,aa<<1);
AddEdge(bb<<1|1,bb<<1);
}
else {
AddEdge(aa<<1,bb<<1|1);
AddEdge(bb<<1,aa<<1|1);
}
}
else {
//printf("here");
// ^
if(t){
AddEdge(aa<<1,bb<<1|1);AddEdge(bb<<1|1,aa<<1);
AddEdge(bb<<1,aa<<1|1);AddEdge(aa<<1|1,bb<<1);
}
else {
AddEdge(aa<<1,bb<<1);AddEdge(bb<<1,aa<<1);
AddEdge(aa<<1|1,bb<<1|1);AddEdge(bb<<1|1,aa<<1|1);
}
}
}
memset(dfn,0,sizeof(dfn));
memset(bleg,0,sizeof(bleg));
times=top=0;
for(int i=1;i<=n;i++){
if(!dfn[i<<1])tarjan(i<<1);
if(!dfn[i<<1|1])tarjan(i<<1|1);
}
for(int i=1;i<=n;i++)
if(bleg[i<<1]==bleg[i<<1|1])flag=1;
//printf("%d:%d\n",k,flag);
if(flag)break;
}
if(flag)puts("NO");
else puts("YES");
}
return 0;
}