2012长春现场赛b Bit Magic

其实一开始我就想到了2-sat,三个地方出现错误

1,内存超了,想到32位各自独立,解决了

2,题目一个条件忽略了,他说i==j时值为0,这个条件应该作为判断条件使用

3,应该用临界表来储存,否则超时

题目地址

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3656

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define Max (500*3+1)
int map[Max][Max];
int num[Max];
int n,array[501][501];
int belong[Max];
int cnt,ind;
int f[Max],low[Max],stack[Max],instack[Max],snum;
int get(int w,int k)
{
    return w*2+k;
 
}
/*int insert(int a,int b)
{
if(map[a].num==0)
{
map[a].to=b;
map[a].num++;
return 0;
}
int i;
M *p=&map[a];
for(i=1;i<map[a].num;i++)
p=p->next;
if(p->next==NULL)
{
p->next=new M;
p->next->next=NULL;
}
p->next->to=b;
map[a].num++;
return 0;
}*/
int insert(int a,int b)
{
 map[a][num[a]++]=b;
 return 0;
}
int tarjan(int x)
{
    int i;
 // M *p=&map[x];
    low[x]=f[x]=++cnt;
    stack[++snum]=x;
    instack[x]=1;
 for(i=0;i<num[x];i++)
 {
  if(!f[map[x][i]])
        {
            tarjan(map[x][i]);
            if(low[map[x][i]]<low[x])
    low[x]=low[map[x][i]];
        }
        else if(instack[map[x][i]]&&f[map[x][i]]<low[x])
   low[x]=f[map[x][i]];
    }
    if(low[x]==f[x])
    {
        while(stack[snum]!=x)
        {
            belong[stack[snum]]=ind;
            instack[stack[snum]]=0;
            snum--;
        }
        belong[stack[snum]]=ind;
        instack[stack[snum]]=0;
        snum--;
        ind++;
    }
    return 0;
}
int main()
{
    int i,j,z,k,flag;
 // for(i=0;i<Max;i++)
 //  map[i].next=NULL;
    while(scanf("%d",&n)!=EOF)
    {
  flag=1;
  for(i=0;i<n;i++)
   for(j=0;j<n;j++)
    scanf("%d",&array[i][j]);
   for(z=0;z<32;z++)
   {
    memset(num,0,sizeof(num));
    // for(i=0;i<=get(n-1,1);i++)
    // map[i].num=0;
    for(i=0;i<n;i++)
    {
     for(j=0;j<n;j++)
     {
      if(i==j)
      {
       if(array[i][j])
       {
        flag=0;
        break;
       }
       continue;
      }
      if(array[i][j]&(1<<z))
      {
       if(i%2&&j%2)
       {
        insert(get(i,0),get(j,1));
        insert(get(j,0),get(i,1));
        
       }
       else if (i % 2 == 0 && j % 2 == 0)
       {
        insert(get(i,1),get(j,1));
        insert(get(j,1),get(i,1));
       }
       else
       {
        insert(get(i,0),get(j,1));
        insert(get(j ,0),get(i ,1));
        insert(get(i ,1),get(j ,0));
        insert(get(j ,1),get(i ,0));
       }
      }
      else
      {
       if(i%2&&j%2)
       {
        insert(get(i ,0),get(j ,0));
        insert(get(j ,0),get(i ,0));
       }
       else if (i % 2 == 0 && j % 2 == 0)
       {
        insert(get(i ,1),get(j ,0));
        insert(get(j ,1),get(i ,0));
       }
       else
       {
        insert(get(i ,0),get(j ,0));
        insert(get(j ,0),get(i ,0));
        insert(get(i ,1),get(j ,1));
        insert(get(j ,1),get(i ,1));
       }
      }
     }
     if(flag==0)
      break;
    }
    if(flag==0)
     break;
    memset(f,0,sizeof(f));
    memset(instack,0,sizeof(instack));
    snum=0;
    cnt=ind=1;
    for(i=0;i<=get(n-1,1);i++)
     if(!f[i])
      tarjan(i);
     for(i=0;i<n;i++)
     {
      if(belong[get(i,0)]==belong[get(i,1)])
      {
       flag=0;
       break;
      }
     }
     if(flag==0)
      break;
   }
   if(flag==0)
    printf("NO\n");
   else
    printf("YES\n");
    }
    return 0;
 
}

 

2-sat 只用对强制条件进行处理,判断是否有矛盾产生,而非强制条件则忽略~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值