【codeforces 776D】The Door Problem

来源:互联网 发布:平面设计和淘宝美工 编辑:程序博客网 时间:2024/06/06 08:50

【题目链接】:http://codeforces.com/contest/776/problem/D

【题意】

每个门严格由两个开关控制;
按一下开关,这个开关所控制的门都会改变状态;
问你能不能使所有的门都打开(同时);

【题解】

/*    对于每个门,    有两个开关连接着它;    用一条边连接这两个开关    则如果这个门的状态是关的,    则这条边的边权为1    表示它们俩的颜色不能一样;    (也即这两个开关只能改变一个)    也即要1开1关;    如果这个门的状态是开的    则这条边的边权为0;    表示它们俩的颜色相同;    即同时开或同时关.    然后做一个二分图染色    可以就是YES否则NO    也就是说把开关看成节点,门看成边,根据边来确定这条边的两端的节点的颜色是一样还是不同;*/


【完整代码】

#include <iostream>#include <vector>#include <cstdio>#include <cstdlib>#define rei(x) cin >> x#define rep1(i,x,y) for (int i = x;i <= y;i++)using namespace std;const int N = 2e5 + 100;int n, m, a[N],color[N];vector <int> g1[N],g[N],w[N];void dfs(int x, int c){    color[x] = c;    int len = g[x].size();    rep1(i, 0, len - 1)    {        int y = g[x][i];        int ju = w[x][i];        if (color[y] != 0)        {            if (ju == 1 && color[y] == color[x])            {                puts("NO");                exit(0);            }            if (ju == 0 && color[y] != color[x])            {                puts("NO");                exit(0);            }        }        else            if (ju == 0)                dfs(y, c);            else                dfs(y, 3 - c);    }}int main(){    //freopen("D:\\rush.txt", "r", stdin);    rei(n),rei(m);    rep1(i, 1, n)        rei(a[i]);    rep1(i, 1, m)    {        int num;        rei(num);        rep1(j, 1, num)        {            int x;            cin >> x;            g1[x].push_back(n + i);            g1[n + i].push_back(x);        }    }       rep1(i, 1, n)    {        int y1 = g1[i][0], y2 = g1[i][1];        int bian = 1 - a[i];        g[y1].push_back(y2), g[y2].push_back(y1);        w[y1].push_back(bian),w[y2].push_back(bian);            }    rep1(i,n+1,n+m)        if (color[i] == 0)            dfs(i, 1);    puts("YES");    return 0;}
0 0
原创粉丝点击