hdu 4421 BitMagic

这是一道区域赛的题目,解法有许多,这边是2-sat的做法

题目大意:自己看题

分析:对于A[i]的每一位做2-SAT,判断是否可行。

主要是建图:

对于a&b=0  有 a-> ┐b, b-> ┐a

a&b=1            ┐a->a , ┐b->b

a|b=0            a-> ┐a,b-> ┐b

a|b=1        ┐a->b, ┐b->a

a^b=0    a->b,b->a, ┐a-> ┐b, ┐b-> ┐a

a^b=1    a-> ┐b,b-> ┐a, ┐a->b, ┐b->a

用Kosaraju算法会T(也许我写渣了)用Tarjan算法就ok╮(╯▽╰)╭

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <set>
  5 #include <algorithm>
  6 #include <map>
  7 #include<vector>
  8 using namespace std;
  9 const int MAXN = 2010;
 10 const int MAXM = 1010*501*2;
 11 struct Edge
 12 {
 13     int to,next;
 14 } edge[MAXM];
 15 int head[MAXN],tot;
 16 void addedge(int u,int v)
 17 {
 18     edge[tot].to = v;
 19     edge[tot].next = head[u];
 20     head[u] = tot++;
 21 }
 22 int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];//Belong数组的值1~scc
 23 int Index,top;
 24 int scc;
 25 bool Instack[MAXN];
 26 int num[MAXN];
 27 void init()
 28 {
 29     tot = 0;
 30     memset(head,-1,sizeof(head));
 31 }
 32 void Tarjan(int u)
 33 {
 34     int v;
 35     Low[u] = DFN[u] = ++Index;
 36     Stack[top++] = u;
 37     Instack[u] = true;
 38     for(int i = head[u]; i != -1; i = edge[i].next)
 39     {
 40         v = edge[i].to;
 41         if( !DFN[v] )
 42         {
 43             Tarjan(v);
 44             if(Low[u] > Low[v])Low[u] = Low[v];
 45         }
 46         else if(Instack[v] && Low[u] > DFN[v])
 47             Low[u] = DFN[v];
 48     }
 49     if(Low[u] == DFN[u])
 50     {
 51         scc++;
 52         do
 53         {
 54             v = Stack[--top];
 55             Instack[v] = false;
 56             Belong[v] = scc;
 57             num[scc]++;
 58         }
 59         while(v != u);
 60     }
 61 }
 62 int maps[1010][1010];
 63 bool solve(int m){
 64     for(int i=0;i<m;++i){
 65         for(int j=0;j<m;++j){
 66             if(i==j&&maps[i][j])return false;
 67             if(maps[i][j]!=maps[j][i])return false;
 68         }
 69     }
 70     for(int k=0;k<31;++k){
 71         init();
 72         for(int i=0;i<m;++i){
 73             for(int j=0;j<m;++j){
 74                 if(i==j)continue;
 75                 int is = maps[i][j]&(1<<k);
 76                 if((i&1)&&(j&1)){//|
 77                     if(is){//a|b=1
 78                         addedge(i,j+m);
 79                         addedge(j,i+m);
 80                     }
 81                     else{//a|b=0
 82                         addedge(i+m,i);
 83                         addedge(j+m,j);
 84                     }
 85                 }
 86                 else if((i%2==0)&&(j%2==0)){//&
 87                     if(is){//a&b=1
 88                         addedge(i,i+m);
 89                         addedge(j,j+m);
 90                     }
 91                     else{//a&b=0
 92                         addedge(i+m,j);
 93                         addedge(j+m,i);
 94                     }
 95                 }
 96                 else {//^
 97                     if(is){//a^b=1
 98                         addedge(i+m,j);
 99                         addedge(j+m,i);
100                         addedge(i,j+m);
101                         addedge(j,i+m);
102                     }
103                     else{//a^b=0
104                         addedge(i+m,j+m);
105                         addedge(j+m,i+m);
106                         addedge(i,j);
107                         addedge(j,i);
108
109                     }
110                 }
111             }
112         }
113         memset(DFN,0,sizeof(DFN));
114         for(int i=0;i<2*m;++i){
115             if(!DFN[i])Tarjan(i);
116         }
117         for(int i=0;i<m;++i){
118             if(Belong[i]==Belong[m+i]){
119                 return false;
120             }
121         }
122     }
123     return true;
124 }
125 int main (){
126     int m;
127     while(scanf("%d",&m)!=EOF){
128         for(int i=0;i<m;++i){
129             for(int j=0;j<m;++j){
130                 scanf("%d",&maps[i][j]);
131             }
132         }
133         if(solve(m))printf("YES\n");
134         else printf("NO\n");
135     }
136 }

hdu 4421 BitMagic

时间: 2024-08-29 16:25:32

hdu 4421 BitMagic的相关文章

HDU 4421 Bit Magic(2-sat)

HDU 4421 Bit Magic 题目链接 题意:就依据题目,给定b数组.看能不能构造出一个符合的a数组 思路:把每一个数字的每一个二进制位单独考虑.就变成一个2-sat题目了,依据题目中的式子建立2-sat的边.然后每一位跑2-sat.假设每位都符合.就是YES,假设有一位不符合就是NO 代码: #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #incl

HDU 4421 Bit Magic(奇葩式解法)

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4421 题目大意: 给了你一段代码, 用一个数组的数 对其进行那段代码的处理,是可以得到一个矩阵 让你判断这个矩阵能否由一个数组转化而来. 思路: 既然每组数据可以得到,那么他肯定能消去. 我们用一个数组P[i][j] 保存 a[i]^a[j]   的值 a[i]^a[j] 我们可用 P[i][j] = P[i][j-1]^a[j-1]^a[j] 这样我们就可以找出所有 P[i][j] = a[i]^

图论(2-sat):HDU 4421 Bit Magic

Bit Magic Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3040    Accepted Submission(s): 871 Problem Description Yesterday, my teacher taught me about bit operators: and (&), or (|), xor (^). I

HDU 4421 Bit Magic (图论-2SAT)

Bit Magic Problem Description Yesterday, my teacher taught me about bit operators: and (&), or (|), xor (^). I generated a number table a[N], and wrote a program to calculate the matrix table b[N][N] using three kinds of bit operator. I thought my ac

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=

hdu 4421 Bit Magic

Bit Magic Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2057    Accepted Submission(s): 590 Problem Description Yesterday, my teacher taught me about bit operators: and (&), or (|), xor (^). I

Bit Magic HDU - 4421

Yesterday, my teacher taught me about bit operators: and (&), or (|), xor (^). I generated a number table a[N], and wrote a program to calculate the matrix table b[N][N] using three kinds of bit operator. I thought my achievement would get teacher's

【图论】2-sat总结

2-sat总结 2-sat问题,一般表现的形式为.每一个点有两种方式a,b,要么选a,要么选b.而且点点之间有一些约束关系.比如:u和v至少一个选a.那么这就是一个表达式.把a当成真,b当成假,那就是u真或v真.2-sat的题目就是这样.给定这些约束,推断是否会矛盾 注意表达式的转化形式,(事实上就是离散数学中那几种转换方式) 比方(u真且v真)或(u假且v假)就能够转化成(u真或v假)且(u假或v真),这样就能建立关系 2-sat中的原理,事实上和2染色是一样的,把每一个结点拆分成一个真结点和

【图论】

2-sat总结 2-sat问题,一般表现的形式为,每个点有两种方式a,b,要么选a,要么选b,并且点点之间有一些约束关系,例如:u和v至少一个选a,那么这就是一个表达式,把a当成真,b当成假,那就是u真或v真,2-sat的题目就是这样,给定这些约束,判断是否会矛盾 注意表达式的转化形式,(其实就是离散数学中那几种转换方式) 比如(u真且v真)或(u假且v假)就可以转化成(u真或v假)且(u假或v真),这样就能建立关系 2-sat中的原理,其实和2染色是一样的,把每个结点拆分成一个真结点和一个假结