题意:

      给你一个数组b[][],在给你一些关系,问是否可以找到一个满足限制的a[],

关系如下(图片):




思路:

      说到限制,而且还是两个两个之间的限制,那么很容易想到2-sat但是这个题目

扎一看还不像,b[i][j]不是只 0 1 2,怎么办呢,其实我们可以一位一位枚举,最多

也就32,对于每一位我们都判断下,只有所有的位数都满足了,才算存在a[],下面说下关键,就是怎么建图。

a[i] | a[j] == 0 说明两个都是0,则           a  ~a ,b ~b.

a[i] | a[j] == 1 说明两个至少有一个是1则    ~a  b ,~b a.

a[i] & a[j] == 1 说明两个都是1,则          ~a  a ,~b b.

a[i] & a[j] == 0 说明至少有一个0 则         b ~a  ,a ~b.

a[i] ^ a[j] == 1 说明两个不同 则            a ~b ,b ~a ,~a b ,~b a

a[i] ^ a[j] == 0 说明两个相同 则            a b ,b ,a ,~a ~b ,~b ~a

然后强连通判断是否可行就行了,这里说一下,之前我强连通用的全是双深搜的那个,一直都可以,知道今天这个题目一直超时,我一开始想不出超时的地方,只能是换了个强连通的算法,用的Tarjan结果1625ms AC了.蛋疼。


#include<stdio.h>
#include<string.h>
#include<stack> #define N_node 1000 + 50
#define N_edge 1000000 + 100

using namespace
std; typedef struct
{
int
to ,next;
}
STAR; STAR E[N_edge];
int
list[N_node] ,tot;
int
DFN[N_node] ,LOW[N_node];
int
Belong[N_node];
int
Index ,num ,okk;
int
instack[N_node];
int
B[550][550];
stack<int>st; void add(int a ,int b)
{

E[++tot].to = b;
E[tot].next = list[a];
list[a] = tot;
} int
minn(int x ,int y)
{
return
x < y ? x : y;
} void
Tarjan(int s)
{

DFN[s] = LOW[s] = Index ++;
st.push(s);
instack[s] = 1;
for(int
k = list[s] ;k ;k = E[k].next)
{
int
to = E[k].to;
if(!
DFN[to])
{

Tarjan(to);
LOW[s] = minn(LOW[to] ,LOW[s]);
}
else if(
instack[to])
{

LOW[s] = minn(DFN[to] ,LOW[s]);
}
}
if(
LOW[s] == DFN[s])
{

num ++;
while(
1)
{
int
v = st.top();
Belong[v] = num;
st.pop();
instack[v] = 0;
if(
v == s) break;
}
}
} bool
ok(int n)
{

memset(instack ,0 ,sizeof(instack));
memset(DFN ,0 ,sizeof(DFN));
memset(LOW ,0 ,sizeof(LOW));
while(!
st.empty()) st.pop();
Index = 1 ,num = 0;
for(int
i = 0 ;i < n * 2 ;i ++)
{
if(
DFN[i]) continue;
Tarjan(i);
}
for(int
i = 0 ;i < n * 2 ;i += 2)
if(
Belong[i] == Belong[i^1]) return 0;
return
1;
} bool
solve(int n )
{
for(int
i = 0 ;i < n ;i ++)
if(
B[i][i]) return 0;
__int64
Key = 1;
for(int
ii = 1 ;ii <= 32 ;ii ++ ,Key *= 2)
{

memset(list ,0 ,sizeof(list));
tot = 1;
for(int
i = 0 ;i < n ;i ++)
for(int
j = 0 ;j < n ;j ++)
{
if(
i == j) continue;
int
now = B[i][j] & Key;
if(
i % 2 && j % 2)
{
if(!
now)
add(i * 2 ,i * 2 + 1) ,add(j * 2 ,j * 2 + 1);
else
add(i * 2 + 1 ,j * 2) ,add(j * 2 + 1 ,i * 2);
}
else if(
i % 2 == 0 && j % 2 == 0)
{
if(!
now)
add(j * 2 ,i * 2 + 1) ,add(i * 2 ,j * 2 + 1);
else
add(i * 2 + 1 ,i * 2) ,add(j * 2 + 1 ,j * 2);
}
else
{
if(!
now)
add(i * 2 ,j * 2) ,add(i * 2 + 1 ,j * 2 + 1),
add(j * 2 ,i * 2) ,add(j * 2 + 1 ,i * 2 + 1);
else

add(i * 2 ,j * 2 + 1) ,add(j * 2 ,i * 2 + 1),
add(i * 2 + 1 ,j * 2) ,add(j * 2 + 1 ,i * 2);
}
}
if(!
ok(n)) return 0;
}
return
1;
} int main ()
{
int
n ,i ,j;
while(~
scanf("%d" ,&n))
{
for(
i = 0 ;i < n ;i ++)
for(
j = 0 ;j < n ;j ++)
scanf("%d" ,&B[i][j]);
solve(n) ? puts("YES") : puts("NO");
}
return
0;
}

hdu4421 2-sat(枚举二进制每一位)的更多相关文章

  1. Java编程的逻辑 (4) - 整数的二进制表示与位运算

    ​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...

  2. USACO2.1 Hamming Codes【枚举+二进制处理+输出格式+题意理解】

    这道题加了2个看起来奇奇怪怪的$tag$ 1.输出格式:不得不说这个格式输出很恶心,很像$UVA$的风格,细节稍微处理不好就会出错. 因为这个还$WA$了一次: ,m=n; ) { ;i<=t+ ...

  3. POJ 1753. Flip Game 枚举or爆搜+位压缩,或者高斯消元法

    Flip Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 37427   Accepted: 16288 Descr ...

  4. 《CLR via C#》---枚举标志和标志位

    枚举类型 枚举类型定义了一组符号名称/值配对. 如 private enum Color /* : byte */ { White, // Assigned a value of 0 Red, // ...

  5. たくさんの数式 / Many Formulas AtCoder - 2067 (枚举二进制)

    Problem Statement You are given a string S consisting of digits between 1 and 9, inclusive. You can ...

  6. img-图片二进制流 64位前端显示

    碰到的场景:因为使用iframe子窗口打开,多张的二维码图片创建方法调用,导致页面打开缓慢, 所以将调取方式转换成<img src="data:image/png;base64,@it ...

  7. poj 3977 Subset(折半枚举+二进制枚举+二分)

    Subset Time Limit: 30000MS   Memory Limit: 65536K Total Submissions: 5721   Accepted: 1083 Descripti ...

  8. 趣题: 按二进制中1的个数枚举1~2^n (位运算技巧)

    ; ; k <= n; k++){ << k)-,u = << n; s < u;){ ;i < n;i++) printf(-i)&); print ...

  9. C# 枚举的flags 标志位应用

    枚举有个特性叫标志位,使用方法如下 [Flags] enum Foo { a =1, b = 2, c = 4, d = 8 } 每个值需要为2的n次方,保证多个值的组合不会重复. 这样在判断其中一个 ...

随机推荐

  1. Zeebe服务学习1-简单部署与实现demo

    1.Zeebe是什么? Camunda公司研发的工作流引擎Zeebe,目标是对微服务的编排.具体详细介绍可以参考官网:https://zeebe.io/what-is-zeebe/ 2.背景 随着微服 ...

  2. pytorch(10)transform模块(进阶)

    图像变换 Pad 对图片边缘进行填充 transforms.Pad(padding,fill=0,padding_mode='constant') padding:设置填充大小,(a,b,c,d)左上 ...

  3. 面试常备,字符串三剑客 String、StringBuffer、StringBuilder

    尽人事,听天命.博主东南大学硕士在读,热爱健身和篮球,乐于分享技术相关的所见所得,关注公众号 @ 飞天小牛肉,第一时间获取文章更新,成长的路上我们一起进步 本文已收录于 「CS-Wiki」Gitee ...

  4. Github Fork与远程主分支同步

    fork与主分支同步(5步) 1. git remote add upstream git@github.com:haichong98/gistandard.git   新建一个upstream的远程 ...

  5. R绘图(3): 散点图添加文本注释

    这里以火山图为例进行说明,在转录组分析中,火山图是很常见的一类图,纵轴表示p_value,横轴表示log (fold change).单一的散点图绘制很简单,火山图比较难处理的地方就是一些基因的注释, ...

  6. 我的2019年总结和一些2020年的flag

    我的2019年总结和一些2020年的flag 前言 2019年在我的人生中注定是里程碑的一年,主要是我毕业了.本篇总结主要聊一些2019年经历的事以及对于自己2020年的期待 1. 再见2019 1. ...

  7. WPF 基础 - 资源

    为了避免丢失和损坏,编译器允许我们把外部文件编译进程序主体.成为程序主体不可分割的一部分,这就是传统意义上的程序资源,即二进制资源: WPF 的四个等级资源: 数据库里的数据 (仓库) 资源文件 (行 ...

  8. [省选联考 2020 A/B 卷] 冰火战士

    一.题目 点此看题 二.解法 其实这道题也不是特别难吧 \(......\) 但树状数组上二分是我第一次见. 我们把冰人和火人都按温度排序,那么考虑一个分界线 \(x\) ,问题就是求冰数组 \(x\ ...

  9. Redis不是一直号称单线程效率也很高吗,为什么又采用多线程了?

    Redis是目前广为人知的一个内存数据库,在各个场景中都有着非常丰富的应用,前段时间Redis推出了6.0的版本,在新版本中采用了多线程模型. 因为我们公司使用的内存数据库是自研的,按理说我对Redi ...

  10. 01-静态web服务器(Python)-面向对象的对比

    普通写法,静态web服务器: 先创建TCP服务器套接字,然后等待客户端(这里是浏览器)请求连接. 客户端发起请求,用线程来处理连接的建立,这样可以实现多任务(也就是并发) 连接后根据请求发送指定页面 ...