CNF 2

'In Boolean logic, a formula is in conjunctive normal form (CNF) or clausal normal form if it is a conjunction of clauses, where a clause is a disjunction of literals' (cited from https://en.wikipedia.org/wiki/Conjunctive_normal_form)

In the other words, CNF is a formula of type , where & represents a logical "AND" (conjunction), represents a logical "OR" (disjunction), and vij are some boolean variables or their negations. Each statement in brackets is called a clause, and vij are called literals.

You are given a CNF containing variables x1, ..., xm and their negations. We know that each variable occurs in at most two clauses (with negation and without negation in total). Your task is to determine whether this CNF is satisfiable, that is, whether there are such values of variables where the CNF value is true. If CNF is satisfiable, then you also need to determine the values of the variables at which the CNF is true.

It is guaranteed that each variable occurs at most once in each clause.

Input

The first line contains integers n and m (1 ≤ n, m ≤ 2·105) — the number of clauses and the number variables, correspondingly.

Next n lines contain the descriptions of each clause. The i-th line first contains first number ki (ki ≥ 1) — the number of literals in the i-th clauses. Then follow space-separated literals vij (1 ≤ |vij| ≤ m). A literal that corresponds to vij is x|vij| either with negation, if vij is negative, or without negation otherwise.

Output

If CNF is not satisfiable, print a single line "NO" (without the quotes), otherwise print two strings: string "YES" (without the quotes), and then a string of m numbers zero or one — the values of variables in satisfying assignment in the order from x1 to xm.

一开始想成了网络流或者二分图匹配,但是增广的时间复杂度太高了。

不过方法是类似的,首先,如果一个变量只出现一种形式,那么就让这个变量出现过的clause为真

,这些变量和对应的clause就可以排除了。如果一个变量出现了两次,那么就把变量var看成是一条边,把clasue看成是一个点

在出现!var的clause U和出现var的clause V直接连一条边,选择var的值就转化成了决定边的方向

规定一个clasue有至少一个入边的时候表示clause为真。贪心,之前已经排除掉的clasue U中出现的还没有决定的变量var都可以当作是对U为假,

那么出现!var的V就全部为真了,这些V也可以排除了,所以可以用bfs或dfs完成这个过程。这是一个连通分量的情况。

对于还没有考虑过的连通分量,如果是一颗树,那么一定不行,因为每次删除只有一条入边的叶子,最后一个会剩下一个点无法使它为真。

是树即无环,因此用dfs找环,如果找到,那么将环中点删去,更新答案,重复bfs增广一个连通分量的操作。如果没找到,那么就输出NO。

因为var和clasue最多被标记一次所以时间复杂是O(n+m)。线性复杂度都跑了405ms,网络流或者二分图匹配怎么可能不T

#include<bits/stdc++.h>
using namespace std; const int maxn = 2e5+; #define PB push_back
vector<int> adj[maxn][];
vector<int> G[maxn],id[maxn];
char ans[maxn];
bool ok[maxn]; int n,m; queue<int> q; #define Add(x)\
ok[x] = true;\
q.push(x) void bfs()
{
while(q.size()){
int u = q.front(); q.pop();
for(int i = , M = G[u].size(); i < M; i++){
int v = G[u][i];
if(ok[v]) continue;
Add(v);
int var = id[u][i];
ans[var] = (v == adj[var][][])+'';
}
}
} bool vis[maxn];
bool dfs(int u,int pvar)
{
if(vis[u]) return true;
vis[u] = true;
for(int i = , M = G[u].size(); i < M; i++){
int v = G[u][i];
int var = id[u][i];
if(var == pvar) continue;
if(dfs(v,var)){
Add(u);
ans[var] = (u == adj[var][][])+'';
return true;
}
}
return false;
} int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
for(int i = ; i < n; i++){
int k; scanf("%d",&k);
int v;
while(k--){
scanf("%d",&v);
int fg = v;
if(v<) v = -v;
adj[--v][fg>].PB(i);
}
} for(int i = ; i < m; i++){
if(adj[i][].empty()){
for(int j = ,M = adj[i][].size(); j < M; j++) {
Add(adj[i][][j]);
}
ans[i] = '';
}else if(adj[i][].empty()){
for(int j = ,M = adj[i][].size(); j < M; j++) {
Add(adj[i][][j]);
}
ans[i] = '';
}else {
int u = adj[i][][], v = adj[i][][];
G[u].PB(v); id[u].PB(i);
G[v].PB(u); id[v].PB(i);
}
}
for(int i = ; i < n; i++){
bfs();
if(ok[i]) continue;
if(!dfs(i,-)){
puts("NO");
return ;
}
} puts("YES");
for(int i = ; i < m; i++){
if(ans[i]) putchar(ans[i]);
else putchar('');
}
return ;
}

Codeforces Round #317 div2 E div1 C CNF 2 (图论,匹配)的更多相关文章

  1. Codeforces Round #539 div2

    Codeforces Round #539 div2 abstract I 离散化三连 sort(pos.begin(), pos.end()); pos.erase(unique(pos.begin ...

  2. 【前行】◇第3站◇ Codeforces Round #512 Div2

    [第3站]Codeforces Round #512 Div2 第三题莫名卡半天……一堆细节没处理,改一个发现还有一个……然后就炸了,罚了一啪啦时间 Rating又掉了……但是没什么,比上一次好多了: ...

  3. Codeforces Round#320 Div2 解题报告

    Codeforces Round#320 Div2 先做个标题党,骗骗访问量,结束后再来写咯. codeforces 579A Raising Bacteria codeforces 579B Fin ...

  4. Codeforces Round #564(div2)

    Codeforces Round #564(div2) 本来以为是送分场,结果成了送命场. 菜是原罪 A SB题,上来读不懂题就交WA了一发,代码就不粘了 B 简单构造 很明显,\(n*n\)的矩阵可 ...

  5. Codeforces Round #361 div2

    ProblemA(Codeforces Round 689A): 题意: 给一个手势, 问这个手势是否是唯一. 思路: 暴力, 模拟将这个手势上下左右移动一次看是否还在键盘上即可. 代码: #incl ...

  6. Codeforces Round #626 Div2 D,E

    比赛链接: Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics) D.Present 题意: 给定大 ...

  7. CodeForces Round 192 Div2

    This is the first time I took part in Codeforces Competition.The only felt is that my IQ was contemp ...

  8. CodeForces Round #250 Div2

    A. The Child and Homework 注意仔细读题,WA了好多次,=_= #include <cstdio> #include <cstring> #includ ...

  9. Codeforces Round #359 div2

    Problem_A(CodeForces 686A): 题意: \[ 有n个输入, +\space d_i代表冰淇淋数目增加d_i个, -\space d_i表示某个孩纸需要d_i个, 如果你现在手里 ...

随机推荐

  1. 【Hadoop】HDFS笔记(二):HDFS的HA机制和Federation机制

    HA解决了HDFS的NameNode的单点问题: Federation解决了整个HDFS集群中只有一个名字空间,并且只有单独的一个NameNode管理所有DataNode的问题. 一.HA机制(Hig ...

  2. 【eclipse插件开发实战】Eclipse插件开发7——插件发布jar包

    Eclipse插件开发7--插件发布jar包 最省事的方式就是直接导出jar包,然后放到eclipse的plugins目录下,重启eclipse即可. step1: 对需要打包的插件工程右击→导出(E ...

  3. SqlServer2012——Select,分组,排序、插入

    1.select 简单语句 --select语句 * --select子句 * AS result --select子句,可以将结果保存在result中 ~~~~~~~~~~~~~~~~~~~~~~~ ...

  4. laravel V层

    V层 即视图层  也就是常用的html页面  但在laravel里后缀为php 视图层路径resources/views/视图名称.php

  5. GPU渲染管线与shader

    1 几何阶段(顶点shader处理这部分) 模型坐标空间-世界坐标空间-观察坐标空间-屏幕坐标空间 其中从观察空间 到 屏幕空间需要经过3步(CVV单位立方体,规范立方体) a用透视变换矩阵把顶点从视 ...

  6. php-fpm 高并发 参数调整

    工作中经常会遇到会给客户配置服务器,其中有的客户还会有并发量要求,其中也会必须要用负载均衡承载压力的.增加服务器数量肯定能有效的提升服务器承载能力,但只有根据目前已有配置设置好单台服务器才能更好的发挥 ...

  7. Mycat(1)

    https://www.jianshu.com/p/26513f428ecf https://blog.csdn.net/fly910905/article/details/87101059 http ...

  8. String的小笔记

    String类的对象是不可变的! 在使用String类的时候要始终记着这个观念.一旦创建了String对象,它就不会改变. String类中也有可以改变String中字符串的方法,但只要是涉及改变的方 ...

  9. python学习之IO:

    输入输出兼程IO操作,有同步(速度不匹配时四等)和异步(轮询和消息通知,复杂而高效) 一 文件操作函数: 文件打开:f=open("文件路径“,“操作类型 r/rb/w/a”,"编 ...

  10. jQuery scrollLeft()与scrollTop() 源码解读

    这里的实现也很容易懂,通过jQuery的静态方法each给jQuery的原型添加scrollLeft和scrollTop方法. 这里在取值时它把window和普通的element做了区分 如果是win ...