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. D - Opponents

    Description Arya has n opponents in the school. Each day he will fight with all opponents who are pr ...

  2. 8、html的body内标签之fieldset标签和label标签

    一.label标签 <label> 标签为 input 元素定义标签(label). label 元素不会向用户呈现任何特殊的样式.不过,它为鼠标用户改善了可用性,因为如果用户点击 lab ...

  3. C#箴言:定义常量的两种方法

    在C#中定义常量的方式有两种, 一种叫做静态常量(Compile-time constant),另一种叫做动态常量(Runtime constant). 前者用"const"来定义 ...

  4. 001-JDK安装

    1.确定JDK的具体版本号 [root@bogon ~]# rpm -qa | grep jdk java-1.7.0-openjdk-1.7.0.91-2.6.2.3.el7.x86_64 java ...

  5. [BZOJ3128]a+b Problem

    题解 最小割+主席树优化建图 首先看到每个点只有\(0/1\)两种状态就想到最小割 然后由于有一个限制是点\(i\)是黑点且有符合条件的白点就会减去\(p_i\) 所以我们将\(S\)集合设为黑点集合 ...

  6. 牛客寒假6-D.美食

    链接:https://ac.nowcoder.com/acm/contest/332/D 题意: 小B喜欢美食. 现在有n个美食排成一排摆在小B的面前,依次编号为1..n,编号为i的食物大小为 a[i ...

  7. 2017"百度之星"程序设计大赛 - 初赛(A)今夕何夕

    Problem Description 今天是2017年8月6日,农历闰六月十五. 小度独自凭栏,望着一轮圆月,发出了“今夕何夕,见此良人”的寂寞感慨. 为了排遣郁结,它决定思考一个数学问题:接下来最 ...

  8. 101 to 010 Atcoder CODE FESTIVAL 2017 qual B D

    https://www.luogu.org/problemnew/show/AT3575 题解 根本不会.. 错误记录:缺少32行的转移.显然这个转移是必要的 #include<cstdio&g ...

  9. FTP任务(重点看断点续传)

    一.FTP任务目录: 1. 多用户同时登陆:     socketserver 2. 用户登陆,加密认证: md5加密 3. 上传/下载文件,保证文件一致性:md5摘要 4. 传输过程中现实进度条 5 ...

  10. python flask学习(1)与Git基础操作

    今天从简单的flask开始完成Flask web开发的学习.今天学习了Git和GitHub项目的提交. Git尝试提交过程中出现了"Could not read from remote re ...