首页 > 代码库 > hdu 4421 和poj3678类似二级制操作(2-sat问题)

hdu 4421 和poj3678类似二级制操作(2-sat问题)

/*
题意:还是二进制异或,和poj3678类似
建边和poj3678一样
*/
#include<stdio.h>
#include<string.h>
#include<math.h>
#define N 2100
struct node{
int v,next;
}bian[N*N];
int head[N],dfn[N],low[N],vis[N],stac[N],belong[N],yong,ans,index,top;
void init() {
yong=index=ans=top=0;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
memset(dfn,0,sizeof(dfn));
}
void addedge(int u,int v) {
bian[yong].v=v;
bian[yong].next=head[u];
head[u]=yong++;
}
int Min(int v,int vv) {
return v>vv?vv:v;
}
void tarjan(int u) {
dfn[u]=low[u]=++index;
stac[++top]=u;
vis[u]=1;
int i;
for(i=head[u];i!=-1;i=bian[i].next) {
    int v=bian[i].v;
    if(!dfn[v]) {
        tarjan(v);
        low[u]=Min(low[u],low[v]);
    }
    else
        if(vis[v])
        low[u]=Min(low[u],dfn[v]);
}
if(dfn[u]==low[u]) {
    ++ans;
    int t;
    do {
        t=stac[top--];
        belong[t]=ans;
        vis[t]=0;
    }while(t!=u);
}
}
int ma[N][N];
int judge(int n) {
int i,j;
for(i=0;i<n;i++) {
    if(ma[i][i])return 1;
    for(j=0;j<n;j++)
    if(ma[i][j]!=ma[j][i])return 1;
}
return 0;
}
int endd(int n) {
int i;
for(i=0;i<2*n;i++)if(!dfn[i])tarjan(i);
for(i=0;i<n;i++)
    if(belong[i]==belong[i+n])
    return 1;
return 0;
}
int main() {
    int n,m,i,j,k;
    while(scanf("%d",&n)!=EOF) {
        for(i=0;i<n;i++)
            for(j=0;j<n;j++)
            scanf("%d",&ma[i][j]);
        if(judge(n)) {
            printf("NO\n");
            continue;
        }
        for(k=0;k<32;k++) {
         init();
            for(i=0;i<n;i++)
            for(j=i+1;j<n;j++) {
                if(i==j)continue;
                m=ma[i][j]&(1<<k);
                if(i%2==1&&j%2==1) {
                    if(m) {
                        addedge(i+n,j);addedge(j+n,i);//0,0
                    }
                    else {
                        addedge(i,j);addedge(j+n,i+n);//1,0
                        addedge(i+n,j+n);addedge(j,i);//0,1
                        addedge(i,j+n);addedge(j,i+n);//1,1
                    }
                }
                else if(i%2==0&&j%2==0) {
                    if(m) {
                      addedge(i,j);addedge(j+n,i+n);//1,0
                      addedge(i+n,j+n);addedge(j,i);//0,1
                      addedge(i+n,j);addedge(j+n,i);//0,0
                    }
                    else {
                          addedge(i,j+n);addedge(j,i+n);//1,1
                    }
                }
                else {
                    if(m) {
                              addedge(i+n,j);addedge(j+n,i);//0,0
                              addedge(i,j+n);addedge(j,i+n);//1,1
                    }
                    else {
                          addedge(i,j);addedge(j+n,i+n);//1,0
                      addedge(i+n,j+n);addedge(j,i);//0,1
                    }
                }
            }
            if(endd(n))break;
        }
        if(k==32)printf("YES\n");
        else
            printf("NO\n");
    }
return 0;}

hdu 4421 和poj3678类似二级制操作(2-sat问题)