Codeforces Round #317 div2 E div1 C CNF 2 (图论,匹配)
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.
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.
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 (图论,匹配)的更多相关文章
- Codeforces Round #539 div2
Codeforces Round #539 div2 abstract I 离散化三连 sort(pos.begin(), pos.end()); pos.erase(unique(pos.begin ...
- 【前行】◇第3站◇ Codeforces Round #512 Div2
[第3站]Codeforces Round #512 Div2 第三题莫名卡半天……一堆细节没处理,改一个发现还有一个……然后就炸了,罚了一啪啦时间 Rating又掉了……但是没什么,比上一次好多了: ...
- Codeforces Round#320 Div2 解题报告
Codeforces Round#320 Div2 先做个标题党,骗骗访问量,结束后再来写咯. codeforces 579A Raising Bacteria codeforces 579B Fin ...
- Codeforces Round #564(div2)
Codeforces Round #564(div2) 本来以为是送分场,结果成了送命场. 菜是原罪 A SB题,上来读不懂题就交WA了一发,代码就不粘了 B 简单构造 很明显,\(n*n\)的矩阵可 ...
- Codeforces Round #361 div2
ProblemA(Codeforces Round 689A): 题意: 给一个手势, 问这个手势是否是唯一. 思路: 暴力, 模拟将这个手势上下左右移动一次看是否还在键盘上即可. 代码: #incl ...
- Codeforces Round #626 Div2 D,E
比赛链接: Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics) D.Present 题意: 给定大 ...
- CodeForces Round 192 Div2
This is the first time I took part in Codeforces Competition.The only felt is that my IQ was contemp ...
- CodeForces Round #250 Div2
A. The Child and Homework 注意仔细读题,WA了好多次,=_= #include <cstdio> #include <cstring> #includ ...
- Codeforces Round #359 div2
Problem_A(CodeForces 686A): 题意: \[ 有n个输入, +\space d_i代表冰淇淋数目增加d_i个, -\space d_i表示某个孩纸需要d_i个, 如果你现在手里 ...
随机推荐
- 4.1-4.2 基于HDFS云盘存储系统分析及hadoop发行版本
一.基于HDFS云盘存储系统 如:某度网盘 优点: *普通的商用机器 内存 磁盘 *数据的安全性 操作: *put get *rm mv *java api *filesystem 核心: *H ...
- python常用第三方库(转载)
Python标准库与第三方库详解(转载) 转载地址: http://www.codeweblog.com/python%e6%a0%87%e5%87%86%e5%ba%93%e4%b8%8e%e7%a ...
- 微信小程序开发之实现https
1:使用自签名的免费ssl证书实现:http://jingyan.baidu.com/article/a948d6515d3e850a2dcd2ee6.html 2:迅雷云购 ...
- Laravel框架之Session操作
//设置session里的值 public function session1(Request $request){ //1.HTTP request session(); /*$request-&g ...
- PHP实用小程序(二)
<HTML> <HEAD> <TITLE>经典循环例子</TITLE> </HEAD> <BODY> <? ; $coun ...
- 51nod 1068【简单博弈】
思路 手动打表, N 1 : A出1 A胜: 2 : A出2 A胜: 3 : A只能出2的整数幂&&这个数<=3,所以只能出1,2:A出1的时候,B就是2的情况,B胜:A出2的时 ...
- 解决overflow: auto在Ios中滑动不流畅
[bug]—— H5页面在 ios 端滑动不流畅的问题 IOS系统的惯性滑动效果非常6,但是当我们对div加overflow-y:auto;后是不会出这个效果的,滑动的时候会感觉很生涩.怎么办? ...
- Memcached 查看帮助
进入到memcached目录, 输入命令: memcached -h 即可查看帮助 -p<num>要侦听的TCP端口号(默认值:11211) -u<num>udp监听端口号(默 ...
- bzoj 3996: [TJOI2015]线性代数【最小割】
把转置矩阵看成逆矩阵吓傻了233 首先按照矩乘推一下式子: \[ D=\sum_{i=1}^n a[i]*(\sum_{j=1}^n a[j]*b[j][i])-c[i] \] \[ D=(\sum_ ...
- bzoj 5120: [2017国家集训队测试]无限之环【最小费用最大流】
玄妙的建图-- 这种平衡度数的题按套路是先黑白染色然后分别连ST点,相邻格子连黑向白连费用1流量0的边,然后考虑费用怎么表示 把一个点拆成五个,上下左右中,中间点黑白染色连ST, 对于连S的点,中点连 ...