博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces Round #400 (Div. 1 + Div. 2, combined)D - The Door Problem(2-sat)
阅读量:4042 次
发布时间:2019-05-24

本文共 3117 字,大约阅读时间需要 10 分钟。

Problem Description

Moriarty has trapped n people in n distinct rooms in a hotel. Some
rooms are locked, others are unlocked. But, there is a condition that
the people in the hotel can only escape when all the doors are
unlocked at the same time. There are m switches. Each switch control
doors of some rooms, but each door is controlled by exactly two
switches.

You are given the initial configuration of the doors. Toggling any

switch, that is, turning it ON when it is OFF, or turning it OFF when
it is ON, toggles the condition of the doors that this switch
controls. Say, we toggled switch 1, which was connected to room 1, 2
and 3 which were respectively locked, unlocked and unlocked. Then,
after toggling the switch, they become unlocked, locked and locked.

You need to tell Sherlock, if there exists a way to unlock all doors

at the same time.

Input

First line of input contains two integers n and m (2 ≤ n ≤ 105,
2 ≤ m ≤ 105) — the number of rooms and the number of switches.

Next line contains n space-separated integers r1, r2, …, rn

(0 ≤ ri ≤ 1) which tell the status of room doors. The i-th room is
locked if ri = 0, otherwise it is unlocked.

The i-th of next m lines contains an integer xi (0 ≤ xi ≤ n) followed

by xi distinct integers separated by space, denoting the number of
rooms controlled by the i-th switch followed by the room numbers that
this switch controls. It is guaranteed that the room numbers are in
the range from 1 to n. It is guaranteed that each door is controlled
by exactly two switches.

Output

Output “YES” without quotes, if it is possible to open all
doors at the same time, otherwise output “NO” without quotes.

Example

Input
3 3 1 0 1 2 1 3 2 1 2 2 2 3
Output
NO
Input
3 3 1 0 1 3 1 2 3 1 2 2 1 3
Output
YES
Input
3 3 1 0 1 3 1 2 3 2 1 2 1 3
Output
NO

因为一个门只由两个开关控制,

所以:
①若该门初始状态为开(1),如果想让门最后的状态为开(1),那么这两个开关都按下或都不按下(这两个开关必须连通,即状态一致),如果只按其中一个,这个门就会变成关(0);
②若该门初始状态为关(0),如果想让门最后的状态为开(1),那么这两个开关只能按其中一个(这两个开关不能连通),如果全按或全不按,这个门都会变成关(0);

当开关个数为m时,开一个2*m大的数组father[],前m个father[i]代表第i个开关按下的状态,后m个father[i]为第i-n个开关没按下的状态;当最后结果father[i]与father[i+n]连通的时候(状态一致),结果矛盾,n个门将不会同时全开,因为一个开关不可能同时两种状态。

判断是否连通要用到 并查集

#include
#include
#include
#include
#include
using namespace std;vector
a[100010]; //相当于二维数组,但更好操作int father[200120],door[100010];int find_father(int x){ if(father[x]==x) return x; return father[x]=find_father(father[x]);}void merge(int x,int y){ int fx=find_father(x); int fy=find_father(y); if(fx!=fy){ father[fx]=fy; }}int main(){ int m,n,flag=1; cin>>n>>m; for(int i=1;i<=n;i++){ cin>>door[i];//门的状态 a[i].clear(); } int k;int x; for(int i=1;i<=2*m;i++) father[i]=i;//初始化,自己是自己的祖先 for(int i=1;i<=m;i++){ cin>>k; for(int j=1;j<=k;j++){ cin>>x; a[x].push_back(i);//把控制同一个门的开关放到一起 } } for(int i=1;i<=n;++i){ if(door[i]){ //如果门开着,两个开关连通 merge(a[i][0],a[i][1]); merge(a[i][0]+m,a[i][1]+m); } else{ //否则,两个开关必须状态不同 merge(a[i][0],a[i][1]+m); merge(a[i][0]+m,a[i][1]); } } for(int i=1;i<=m;i++){ if(find_father(i)==find_father(i+m)){ flag=0; break; } } if(flag) cout<<"YES\n"; else cout<<"NO\n"; return 0;}

转载地址:http://djmdi.baihongyu.com/

你可能感兴趣的文章
带WiringPi库的交叉编译如何处理一
查看>>
带WiringPi库的交叉笔译如何处理二之软链接概念
查看>>
Spring事务的七种传播行为
查看>>
ES写入找不到主节点问题排查
查看>>
Java8 HashMap集合解析
查看>>
欢迎使用CSDN-markdown编辑器
查看>>
Android计算器实现源码分析
查看>>
Android系统构架
查看>>
Android 跨应用程序访问窗口知识点总结
查看>>
各种排序算法的分析及java实现
查看>>
SSH框架总结(框架分析+环境搭建+实例源码下载)
查看>>
js弹窗插件
查看>>
自定义 select 下拉框 多选插件
查看>>
js判断数组内是否有重复值
查看>>
js获取url链接携带的参数值
查看>>
gdb 调试core dump
查看>>
gdb debug tips
查看>>
arm linux 生成火焰图
查看>>
linux和windows内存布局验证
查看>>
linux insmod error -1 required key invalid
查看>>