#include<stdio.h> #include<algorithm> #include<string.h> #include<math.h> #include<queue> #include<vector> #include<map> using namespace std; long long maxn=200005; vector<int>g[200005]; int a[200005]; struct TwoSAT { int n; vector<int>G[400010]; bool mark[400010]; int S[400010], c; bool dfs(int x) { if(mark[x^1]) return false; if(mark[x]) return true; mark[x] = true; S[c++] = x; for(int i = 0; i < G[x].size(); i++) if(!dfs(G[x][i])) return false; return true; } void init(int n) { this->n = n; for(int i = 0; i < n * 2; i++) G[i].clear(); memset(mark, false, sizeof(mark)); } void add_clause(int x, int xval, int y, int yval) { x = x * 2 + xval; y = y * 2 + yval; G[x^1].push_back(y); G[y^1].push_back(x); } bool solve() { for(int i = 0; i < n * 2; i += 2) if(!mark[i] && !mark[i+1]) { c = 0; if(!dfs(i)) { while(c > 0) mark[S[--c]] = false; if(!dfs(i+1)) return false; } } return true; } }solver; int main() { int n,m; scanf("%d%d",&n,&m); for(int i=0;i<n;i++)scanf("%d",&a[i]); for(int i=0;i<m;i++) { int x; scanf("%d",&x); for(int j=1;j<=x;j++) { int u; scanf("%d",&u); u--; g[u].push_back(i); } } solver.init(m); for(int i=0;i<n;i++) { int u=g[i][0]; int v=g[i][1]; solver.add_clause(u,0,v,a[i]==1?1:0); solver.add_clause(u,1,v,a[i]==1?0:1); } if(solver.solve()==1)printf("YES\n"); else printf("NO\n"); return 0; }
|