【题意】

这个函数是给A求B的,现在给你B,问你是否能有A的解存在。

【2-SAT解法】

对于每个A[i]的每一位运行2-sat算法,只要跑到强连通就可以结束,应为只要判断是否有解,后面拓扑求解就不需要了。构图和算法思想和基本的2-sat一致,详见我的2-sat博文。

 #include <stdio.h>
#include <string.h>
inline int min(int a,int b){return a>b?b:a;}
struct edge
{
int v,next;
edge(int d=,int n=-):v(d),next(n){}
void set(int d,int n){v=d;next=n;}
}data[*];
int head[],hn;
void adde(int a,int b)
{
data[hn].set(b,head[a]);
head[a]=hn++;
}
int n;
int b[][];
int dfn[],low[],sta[],belong[];
bool ifin[];
int top,group,dep;
void tarjan(int u)
{
dfn[u]=low[u]=++dep;
sta[++top]=u;
ifin[u]=true;
for (int i=head[u];i!=-;i=data[i].next)
{
int v=data[i].v;
if (!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
} else
{
if (ifin[v]) low[u]=min(low[u],dfn[v]);
}
}
if (dfn[u]==low[u])
{
int j;
++group;
do
{
j=sta[top--];
belong[j]=group;
ifin[j]=false;
} while (u!=j);
}
}
void init()
{
hn=dep=group=;
top=-;
memset(head,-,sizeof head);
memset(dfn,,sizeof dfn);
memset(ifin,false,sizeof ifin);
}
bool judge()
{
for (int i=;i<n;++i)
if (belong[i]==belong[i+n]) return false;
return true;
}
bool solve()
{
for (int i=;i<n;++i)
for (int j=i;j<n;++j)
{
if (i==j && b[i][j]) return false;
if (b[i][j]!=b[j][i]) return false;
}
for (int k=;k<;++k)
{
init();
for (int i=;i<n;++i)
for (int j=i;j<n;++j)
{
int m=b[i][j]&(<<k);
if (i==j) continue;
if (i& && j&) // |
{
if (m)
{
adde(i,j+n);
adde(j,i+n);
} else
{
adde(i+n,i);
adde(j+n,j);
}
} else if (!(i&) && !(j&)) //&
{
if (m)
{
adde(i,i+n);
adde(j,j+n);
} else
{
adde(i+n,j);
adde(j+n,i);
}
} else // ^
{
if (m)
{
adde(i,j+n);
adde(j,i+n);
adde(j+n,i);
adde(i+n,j);
} else //==
{
adde(i,j);
adde(j,i);
adde(i+n,j+n);
adde(j+n,i+n);
}
}
}
for (int i=;i<(n<<);++i)
if (!dfn[i]) tarjan(i);
if (!judge()) return false;
}
return true;
}
int main()
{
while (~scanf("%d",&n))
{
for (int i=;i<n;++i)
for (int j=;j<n;++j)
scanf("%d",&b[i][j]);
if (solve()) puts("YES"); else puts("NO");
}
}

2-sat

【并查集】

主要思想是以A中每个元素的每一位作为一个基本单位,根据b中的值来确定每一位之间的等价关系,值相等的并在一个集合,每当能确定一个新的关系时验证原先的关系是否矛盾。不过在处理的时候有点小技巧,与2-sat的思想类似,扩充成2N个点,对于每一位,有个点代表其值,另一点代表其值的反。能确定一位的值时要同时更新这2点,从一方面说是充分发掘信息,另一方面说是为了异或运算的判断服务,因为异或不能确定一个值,但能确定相对关系,需要用到反。

并查集的算法在这题里比2-SAT的快,剩了些不必要的计算,思想也挺巧妙的。

 #include <stdio.h>
#include <string.h>
#define N 501*32
#define m1 mset.find(1)
#define m0 mset.find(0)
struct myset
{
int uset[*+];
myset(){init();};
void init(){memset(uset,-,sizeof uset);}
int find(int k)
{
if (uset[k]==-) return k;
return uset[k]=find(uset[k]);
}
void uion(int a,int b)
{
int aa=find(a);
int bb=find(b);
if (aa==bb) return;
uset[aa]=bb;
}
}mset;
int b[][],n;
bool solve()
{
for (int i=;i<n;++i)
for (int j=i;j<n;++j)
{
if (i==j && b[i][j]) return false;
if (b[i][j]!=b[j][i]) return false;
}
for (int i=;i<n;++i)
for (int j=;j<n;++j)
{
if (i==j) continue;
if (i& && j&)
{
for (int k=;k<;++k)
{
if (b[i][j]&(<<k) == )
{
int p1=i*+k+;
int p2=j*+k+;
if (mset.find(p1)==m1 || mset.find(p2)==m1 || mset.find(p1)==mset.find(p2+N)) return false;
mset.uion(p1,);
mset.uion(p2,);
mset.uion(p1+N,);
mset.uion(p2+N,);
}
}
} else
if (!(i&) && !(j&))
{
for (int k=;k<;++k)
{
if (b[i][j]&(<<k))
{
int p1=i*+k+;
int p2=j*+k+;
if (mset.find(p1)==m0 || mset.find(p2)==m0 || mset.find(p1)==mset.find(p2+N)) return false;
mset.uion(p1,);
mset.uion(p2,);
mset.uion(p1+N,);
mset.uion(p2+N,);
}
}
} else
{
for (int k=;k<;++k)
{
int p1=i*+k+;
int p2=j*+k+;
if (b[i][j]&(<<k))
{
if (mset.find(p1)==mset.find(p2)) return false;
mset.uion(p1,p2+N);
mset.uion(p2,p1+N);
} else
{
if (mset.find(p1)==mset.find(p2+N) ) return false;
mset.uion(p1,p2);
mset.uion(p1+N,p2+N);
}
}
}
}
return true;
}
int main()
{
while (~scanf("%d",&n))
{
mset.init();
for (int i=;i<n;++i)
for (int j=;j<n;++j)
scanf("%d",&b[i][j]);
if (solve()) puts("YES"); else puts("NO");
}
}

并查集

hdu 4421 Bit Magic的更多相关文章

  1. HDU 4421 Bit Magic(2-sat)

    HDU 4421 Bit Magic pid=4421" target="_blank" style="">题目链接 题意:就依据题目,给定b数 ...

  2. HDU 4421 Bit Magic(奇葩式解法)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4421 题目大意: 给了你一段代码, 用一个数组的数 对其进行那段代码的处理,是可以得到一个矩阵 让你判 ...

  3. HDU 4421 Bit Magic (图论-2SAT)

    Bit Magic Problem Description Yesterday, my teacher taught me about bit operators: and (&), or ( ...

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

    Bit Magic Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  5. hdu 3183 A Magic Lamp(RMQ)

    题目链接:hdu 3183 A Magic Lamp 题目大意:给定一个字符串,然后最多删除K个.使得剩下的组成的数值最小. 解题思路:问题等价与取N-M个数.每次取的时候保证后面能取的个数足够,而且 ...

  6. hdu 3183 A Magic Lamp RMQ ST 坐标最小值

    hdu 3183 A Magic Lamp RMQ ST 坐标最小值 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3183 题目大意: 从给定的串中挑 ...

  7. HDU 3183.A Magic Lamp-区间找最小值-RMQ(ST)

    A Magic Lamp Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  8. HDU 4421 ZOJ 3656 Bit Magic

    2-SAT,不要所有位置全部建好边再判断,那样会MLE的. 正解是,每一位建好边,就进行一次2-SAT. #include<cstdio> #include<cstring> ...

  9. HDU 3183 - A Magic Lamp - [RMQ][ST算法]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3183 Problem DescriptionKiki likes traveling. One day ...

随机推荐

  1. JAX-RS入门 一 :基础

    简介 JAX-RS是一套用java实现REST服务的规范,提供了一些标注将一个资源类,一个POJOJava类,封装为Web资源.标注包括: @Path,标注资源类或方法的相对路径 @GET,@PUT, ...

  2. Programming pages of Jasper Neumann

    http://programming.sirrida.de/ Discussion topics Bit permutations Download source files List of func ...

  3. javascript、jquery获取网页的高度和宽度

    javascript: 可视区域宽 :document.documentElement.clientWidth  (width + padding) 可视区域高 :document.documentE ...

  4. CSS实现标题右侧“更多”

    HTML < h2>< a h ref="#" >标题< /a> < span>更多…< /span> < /h2 ...

  5. UIImage imageNamed 与 imageWithContentsOfFile的差别

    [UIImage imageNamed:]仅仅适合与UI界面中的贴图的读取,较大的资源文件应该尽量避免使用 用UIImage载入本地图像最经常使用的是以下三种: 1.用imageNamed方法 [UI ...

  6. linux下的块设备驱动(一)

    块设备的驱动比字符设备的难,这是因为块设备的驱动和内核的联系进一步增大,但是同时块设备的访问的几个基本结构和字符还是有相似之处的. 有一句话必须记住:对于存储设备(硬盘~~带有机械的操作)而言,调整读 ...

  7. Python 存储模型

    1.Python彻底分离了对象和引用,可以认为内存中的对象都是不可修改的,每次修改引用,相当于在堆上重新创建一个对象,引用指向新对象. 2.对于数值和字符串,修改意味着引用指向一个新对象. 3.集合中 ...

  8. 「译」JavaScript 的怪癖 1:隐式类型转换

    原文:JavaScript quirk 1: implicit conversion of values 译文:「译」JavaScript 的怪癖 1:隐式类型转换 译者:justjavac 零:提要 ...

  9. MySQL错误:Can't connect to MySQL server (10060)

    转自:http://database.51cto.com/art/201107/274565.htm 当远程连接MySQL数据库的时候显示Can't connect to MySQL server ( ...

  10. centos 服务器配置(一) 之端口占用

    1.查找被占用的端口 netstat -tln netstat -tln | grep 8060 netstat -tln 查看端口使用情况,而netstat -tln | grep 8060则是只查 ...