Codeforces Round #400 D. The Door Problem(2-sat)

题目链接:Codeforces Round #400 D. The Door Problem

题意:

有n扇门,每扇门有个初始状态,并且受两个开关控制。

现在给你m个开关控制门的信息,每个开关能将它所控制的门的状态翻转。

问能不能通过一定操作,将所以的门的状态都处于开的情况。

题解:

这题用2sat,也可以用并查集判断联通块。这里我用2sat。

因为一个开关可以控制多扇门,而每个门只由两个开关控制,所以这里我们考虑对这m个开关建图。

如果这扇门的状态为1,那么要让它保持1的状态,我们只能同时按下控制它的两个开关或者两个都不按。

如果这扇门的状态为0,那么我们必须按并且只能按其中一个控制这扇门的开关。

然后根据这个建图。

 1 #include<bits/stdc++.h>
 2 #define mst(a,b) memset(a,b,sizeof(a))
 3 #define F(i,a,b) for(int i=a;i<=b;++i)
 4 using namespace std;
 5 const int N=1e5+7;
 6 namespace Twosat
 7 {
 8     int q[N*4],t,n,g[N*2],v[N*4],nxt[N*4],ed;bool vis[N*2];
 9     void init(int _n){n=_n,mst(g,0),mst(vis,0),ed=0;}
10     void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;}
11     bool dfs(int x){
12         if(vis[x>n?x-n:x+n])return 0;
13         if(vis[x])return 1;
14         vis[q[++t]=x]=1;
15         for(int i=g[x];i;i=nxt[i])if(!dfs(v[i]))return 0;
16         return 1;
17     }
18     bool solve(){
19         F(i,1,n)if(!vis[i]&&!vis[i+n]){
20             t=0;
21             if(!dfs(i)){
22                 while(t)vis[q[t--]]=0;
23                 if(!dfs(i+n))return 0;
24             }
25         }
26         return 1;
27     }
28 }
29 int n,m,a[N],t,u,v,x;
30
31 vector<int>q[N];
32
33 int main(){
34     scanf("%d%d",&n,&m);
35     Twosat::init(m);
36     F(i,1,n)scanf("%d",a+i);
37     F(i,1,m)
38     {
39         scanf("%d",&t);
40         while(t--)
41         {
42             scanf("%d",&x);
43             q[x].push_back(i);
44         }
45     }
46     F(i,1,n)
47     {
48         int u=q[i][0],v=q[i][1];
49         if(a[i])
50         {
51             Twosat::adg(u+m,v+m),Twosat::adg(v+m,u+m);
52             Twosat::adg(u,v),Twosat::adg(v,u);
53         }
54         else {
55             Twosat::adg(u+m,v),Twosat::adg(v,u+m);
56             Twosat::adg(u,v+m),Twosat::adg(v+m,u);
57         }
58     }
59     Twosat::solve()?puts("YES"):puts("NO");
60     return 0;
61 }

时间: 2024-09-29 18:00:46

Codeforces Round #400 D. The Door Problem(2-sat)的相关文章

Codeforces Round #400 C 前缀和,思维

ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) C. Molly's Chemicals 题意:n个数,问有多少个区间的和是k的次方数,即sum([l, r])=k^x, x>=0. abs(k)<=10. tags:一开始O(n^2)统计,果然炸了.. 这题要在统计到第 i 个数时,看s[i]-k^x是否在前面出现过.因为k指数增长很快,这样就是O(n). // #400 #include<b

Codeforces Round #400 E. The Holmes Children

题目链接:Codeforces Round #400 E. The Holmes Children 题意: 定义f(1)=1,f(n),n>1的值为满足x+y=n且gcd(x,y)=1的(x,y)个数:定义g(n)=Σd|n f(n/d):定义Fk(n)满足k=1时Fk(n)=f(g(n)),k>1且k mod 2=0时Fk(n)=g(Fk-1(n)),k>1且k mod 2=1时Fk(n)=f(Fk-1(n)) .给出n,k,求Fk(n)mod 1000000007.(1<=n,

Codeforces Round #400 C. Molly&#39;s Chemicals

题目链接:Codeforces Round #400 C. Molly's Chemicals 题意: 给你n个数,和一个数k,现在问你有多少个区间和等于k的r次方,r从0到无穷. 题解: 由于有负数的存在,不能用双指针,我们先把前缀和sum求出来. 现在就转换为要求有多少个sum[r]-sum[l]=pow(k,r),其中r>l. 因为从数据范围来看,r最大只有lg(1e14),所以我们可以将式子变为sum[r]-pow(k,r)=sum[l]. 然后将sum[l]放进map里,一次for就可

ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) C

Molly Hooper has n different kinds of chemicals arranged in a line. Each of the chemicals has an affection value, The i-th of them has affection value ai. Molly wants Sherlock to fall in love with her. She intends to do this by mixing a contiguous se

ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined)

前四题比较水,E我看出是欧拉函数傻逼题,但我傻逼不会,百度了下开始学,最后在加时的时候A掉了 AC:ABCDE Rank:182 Rating:2193+34->2227 终于橙了,不知道能待几天 A.A Serial Killer 题目大意:一开始给你两个字符串,每次给你当前两个串中的一个和一个新的串,用新的串换掉旧的,每次输出当前的串.(次数<=1000) 思路:二逼题 #include<iostream> using namespace std; int main() { s

ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) A

Our beloved detective, Sherlock is currently trying to catch a serial killer who kills a person each day. Using his powers of deduction, he came to know that the killer has a strategy for selecting his next victim. The killer starts with two potentia

ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) D

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. E

[Codeforces Round #296 div2 D] Clique Problem 【线段树+DP】

题目链接:CF - R296 - d2 - D 题目大意 一个特殊的图,一些数轴上的点,每个点有一个坐标 X,有一个权值 W,两点 (i, j) 之间有边当且仅当 |Xi - Xj| >= Wi + Wj. 求这个图的最大团. 图的点数 n <= 10^5. 题目分析 两点之间右边满足 Xj - Xi >= Wi + Wj (Xi < Xj)       ==>     Xj  - Wj >= Xi + Wi (Xi < Xj) 按照坐标 x 从小到大将点排序.用

Educational Codeforces Round 46 D. Yet Another Problem On a Subsequence

题目大意 定义一个数列是"好的":第一个数字a[0]为数列长度+1. 定义一个数列的子序列是"好的":这个子序列能分割成几个"好的"数列. 各一个数列,求"好的"子序列的数目. 解题思路 一开始想用dp[i][j]表示[i,j]的"好的"子序列的数目.发现复杂度爆炸,而且会造成重复. 为了减少复杂度,避免重复.dp[i]表示后缀i,以a[i]为起始的"好的"子序列的数目.由于一个&quo