码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 776D:The Door Problem(DFS染色)

时间:2017-02-25 11:49:37      阅读:527      评论:0      收藏:0      [点我收藏+]

标签:namespace   false   pre   clu   sizeof   name   情况   int   表示   

http://codeforces.com/problemset/problem/776/D

题意:有n个门,m个开关,每个门有一个当前的状态(0表示关闭,1表示打开),每个开关控制k个门,但是每个门确切的受两个开关控制,如果一个开关打开,那么原来关闭的门会打开,打开的门关闭,问是否存在一个情况使得所有的门打开。

思路:类似于01染色,把开关当成点,门当前的状态当成边权建图。初始先假设一个门的状态(初始假设为0和假设为1都是一样的,举几个例子就发现了),然后因为每个门受两个开关控制,所以可以推出下一个门的状态,如果发现互斥的情况,那么就是“NO”。

这里设成门状态0表示打开,1表示关闭,方便运算。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define N 200010
 4 struct Edge {
 5     int v, nxt, w;
 6 } edge[N*2];
 7 int col[N], fir[N], sec[N], head[N], tot, w[N];
 8 
 9 void Add(int u, int v, int w) {
10     edge[tot] = (Edge) {v, head[u], w}; head[u] = tot++;
11     edge[tot] = (Edge) {u, head[v], w}; head[v] = tot++;
12 }
13 
14 bool dfs(int u) {
15     for(int i = head[u]; ~i; i = edge[i].nxt) {
16         int v = edge[i].v, w = edge[i].w;
17         if(col[v] == -1) { // 如果这个开关没染色
18             col[v] = col[u] ^ w;
19             if(!dfs(v)) return false;
20         } else if(col[u] ^ col[v] ^ w) return false; // 如果染过色并发生矛盾
21     }
22     return true;
23 }
24 
25 int main() {
26     int n, m;
27     cin >> n >> m;
28     for(int i = 1; i <= n; i++) scanf("%d", &w[i]), w[i] ^= 1;
29     for(int i = 1; i <= m; i++) {
30         int k; scanf("%d", &k);
31         while(k--) {
32             int a; scanf("%d", &a);
33             if(fir[a] == 0) fir[a] = i; // 连a点的第一个开关
34             else sec[a] = i; // 连a点的第二个开关
35         }
36     }
37     memset(head, -1, sizeof(head)); tot = 0;
38     for(int i = 1; i <= n; i++)
39         Add(fir[i], sec[i], w[i]);
40     memset(col, -1, sizeof(col));
41     bool flag = 1;
42     for(int i = 1; i <= m; i++) {
43         if(col[i] == -1) {
44             col[i] = 0; // 假设这个开关一开始是关的
45             if(!dfs(i)) { flag = 0; break; }
46         }
47     }
48     if(!flag) puts("NO");
49     else puts("YES");
50     return 0;
51 }

 

Codeforces 776D:The Door Problem(DFS染色)

标签:namespace   false   pre   clu   sizeof   name   情况   int   表示   

原文地址:http://www.cnblogs.com/fightfordream/p/6441216.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!