ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF776D The Door Problem

2020-01-30 21:56:38  阅读:302  来源: 互联网

标签:texttt Door int register 为开 开关 CF776D Problem SAT


考虑 \(\texttt{2-SAT}\)

首先每个门 \(i\) 都有一个初始状态 \(a_i\)

题目条件每个门只被两个开关控制,那么很显然的 \(\texttt{2-SAT}\)

用 \(b_{i,{0/1}}\)记录是第 \(1/2\) 个开关
然后就考虑一下门的初始状态 \(a_i\)

  • 门本身是开的

你开这个开关为开,另一个也要是开的,
反之亦然,所以建两对双向边

  • 门本身是关的

你开这个开关为开,另一个必须是关的
反之亦然,所以还是建两对双向边

然后根据 \(\texttt{2-SAT}\) 的性质,可得答案

#include<bits/stdc++.h>
using namespace std ;
int n , m ;
const int N = 2e5 + 10 ;
int a[N] ;
int b[N][2] ;
struct Edge { int v , nxt ; } e[N << 2] ;
int head[N << 1] , cnt = 0 ;
inline void add(int u , int v) {e[++ cnt] = { v, head[u]} ; head[u] = cnt ; }
int dfn[N << 1] , low[N << 1] , idx = 0 , st[N << 1], tp = 0 , co[N << 1] , num = 0 ;
inline void tarjan(int u) { dfn[u] = low[u] = ++ idx ; st[++ tp] = u ;
  for(register int i = head[u] ; i ; i = e[i].nxt) { int v = e[i].v ;
    if(! dfn[v]){ tarjan(v) ; low[u] = min(low[u] , low[v]) ; }
    else if(! co[v]) { low[u] = min(low[v] , dfn[v]) ; }
  } if(low[u] == dfn[u]) { co[u] = ++ num ; while(st[tp] ^ u) co[st[tp --]] = num ; tp -- ; }
}
signed main() {
#ifdef _WIN64
  freopen("0.in"  , "r" , stdin) ;
#endif
  ios :: sync_with_stdio(false) ; cin.tie(nullptr) ; cout.tie(nullptr) ;
  memset(a , 0 , sizeof(a)) ; memset(b , 0 , sizeof(b)) ;
  cin >> n >> m ;
  for(register int i = 1 ; i <= n ; i ++) { cin >> a[i] ; }
  for(register int i = 1 ; i <= m ; i ++) { int t ; cin >> t ;
    for(register int j = 1 ; j <= t ; j ++) { int x ; cin >> x ; if(b[x][0]) { b[x][1] = i ; } else b[x][0] = i ; }
  }
  for(register int i = 1 ; i <= n ; i ++) {
    if(a[i]) { add(b[i][0] , b[i][1]) ; add(b[i][1] , b[i][0]) ; add(b[i][0] + m , b[i][1] + m) ; add(b[i][1] + m , b[i][0] + m) ; }
    else { add(b[i][0] , b[i][1] + m) ; add(b[i][1] + m , b[i][0]) ; add(b[i][1] , b[i][0] + m) ; add(b[i][0] + m , b[i][1]) ; }
  }
  for(register int i = 1 ; i <= m * 2 ; i ++) { if(! dfn[i]) tarjan(i) ; }
  for(register int i = 1 ; i <= m ; i ++) if(co[i] == co[i + m]) { return cout << "NO\n" , 0 ; }
  cout << "YES\n" ;
  return 0 ;
}

标签:texttt,Door,int,register,为开,开关,CF776D,Problem,SAT
来源: https://www.cnblogs.com/Isaunoya/p/12244084.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有