hdu4421 2-sat(枚举二进制每一位)
题意:
给你一个数组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(枚举二进制每一位)的更多相关文章
- Java编程的逻辑 (4) - 整数的二进制表示与位运算
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...
- USACO2.1 Hamming Codes【枚举+二进制处理+输出格式+题意理解】
这道题加了2个看起来奇奇怪怪的$tag$ 1.输出格式:不得不说这个格式输出很恶心,很像$UVA$的风格,细节稍微处理不好就会出错. 因为这个还$WA$了一次: ,m=n; ) { ;i<=t+ ...
- POJ 1753. Flip Game 枚举or爆搜+位压缩,或者高斯消元法
Flip Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 37427 Accepted: 16288 Descr ...
- 《CLR via C#》---枚举标志和标志位
枚举类型 枚举类型定义了一组符号名称/值配对. 如 private enum Color /* : byte */ { White, // Assigned a value of 0 Red, // ...
- たくさんの数式 / Many Formulas AtCoder - 2067 (枚举二进制)
Problem Statement You are given a string S consisting of digits between 1 and 9, inclusive. You can ...
- img-图片二进制流 64位前端显示
碰到的场景:因为使用iframe子窗口打开,多张的二维码图片创建方法调用,导致页面打开缓慢, 所以将调取方式转换成<img src="data:image/png;base64,@it ...
- poj 3977 Subset(折半枚举+二进制枚举+二分)
Subset Time Limit: 30000MS Memory Limit: 65536K Total Submissions: 5721 Accepted: 1083 Descripti ...
- 趣题: 按二进制中1的个数枚举1~2^n (位运算技巧)
; ; k <= n; k++){ << k)-,u = << n; s < u;){ ;i < n;i++) printf(-i)&); print ...
- C# 枚举的flags 标志位应用
枚举有个特性叫标志位,使用方法如下 [Flags] enum Foo { a =1, b = 2, c = 4, d = 8 } 每个值需要为2的n次方,保证多个值的组合不会重复. 这样在判断其中一个 ...
随机推荐
- Docker 下Elasticsearch 的安装 和ik分词器
(1)docker镜像下载 docker pull elasticsearch:5.6.8 (2)安装es容器 docker run -di --name=changgou_elasticsearch ...
- 微信小程序日期转时间戳
let date = '2019-10-14'; var repTime = date.replace(/-/g, '/'); var timeTamp = Date.parse(repTime) / ...
- 【转载】几张图轻松理解String.intern()
出处:https://blog.csdn.net/soonfly/article/details/70147205 在翻<深入理解Java虚拟机>的书时,又看到了2-7的 String.i ...
- MySQL--WHERE专题
MySQL进阶----过滤条件 select * from ... where ...; 通常我们并不需要查看一个表的所有行,我们需要查看的是具备某种条件的行.前面MySQL使用的基础学习中,就使用过 ...
- [Elementary Mechanics Using Python-02]Feather in tornado
Problem 9.17 Feather in tornado. In this project you will learn to use Newton's laws and the force m ...
- 后台开发:核心技术与应用实践 -- C++
本书介绍的"后台开发"指的是"服务端的网络程序开发",从功能上可以具体描述为:服务器收到客户端发来的请求数据,解析请求数据后处理,最后返回结果. C++编程常用 ...
- 在Asp.Net Core 5 中使用EF Core连接MariaDB
升级到Asp.Net Core 5,使用EF Core连接MariaDB,使用的Nuget包Pomelo.EntityFrameworkCore.MySql也升级到了5.0.0-alpha.2,然后发 ...
- MySQL 40题练习题和答案
2.查询"生物"课程比"物理"课程成绩高的所有学生的学号: 思路: 获取所有有生物课程的人(学号,成绩) - 临时表 获取所有有物理课程的人(学号, ...
- CNN结构演变总结(三)设计原则
CNN结构演变总结(一)经典模型 CNN结构演变总结(二)轻量化模型 前言: 前两篇对一些经典模型和轻量化模型关于结构设计方面的一些创新进行了总结,在本文将对前面的一些结构设计的原则,作用进行总结. ...
- vue Element-ui el-menu 左侧导航条
<template> <!--实现左侧导航条动态渲染(三级)--> <el-menu class="el-menu-vertical-demo" @o ...