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
");
            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
");
        else
            printf("NO
");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410546.html