CodeForces 776D 2-SAT
CodeForces 776D
题意:n个开关,m个房间,每个房间一定由两个开关控制,给出初始房间状态,问是否能把房间全部打开。
tags:因为每个房间一定由两个开关控制,把开关当变量,房间初始状态当条件,按2-SAT建边,然后dfs判断即可。
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a;i<=b;i++) #define per(i,b,a) for (int i=b;i>=a;i--) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f #define MP make_pair #define PB push_back #define fi first #define se second typedef long long ll; const int N = 200005; int n, m, room[N], a[N], b[N]; bool vis[N<<1]; vector<int > G[N<<1]; void Addedge(int u, int v) { G[u].PB(v); G[v].PB(u); } int sta[N<<2], top; bool dfs(int u) { if(vis[u^1]) return false; if(vis[u]) return true; vis[u]=true, sta[top++]=u; for(auto v : G[u]) if(!dfs(v)) return false; return true; } int main() { scanf("%d %d", &n, &m); rep(i,1,n) scanf("%d", &room[i]); int xi, ai; rep(i,1,m) { scanf("%d", &xi); rep(j,1,xi) { scanf("%d", &ai); if(a[ai]==0) a[ai]=i; else b[ai]=i; } } rep(i,1,n) { int x=a[i], y=b[i]; if(room[i]==0) Addedge(2*x, 2*y+1), Addedge(2*x+1, 2*y); else Addedge(2*x, 2*y), Addedge(2*x+1, 2*y+1); } mes(vis, false); for(int i=2; i<=m*2; i+=2) { if(vis[i]==false && vis[i+1]==false) { top=0; if(!dfs(i)) { while(top>0) vis[sta[--top]]=false; if(!dfs(i+1)) return 0*printf("NO"); } } } puts("YES"); return 0; }