• Codeforces 776D:The Door Problem


    Codeforces 776D:The Door Problem

    题目链接:http://codeforces.com/problemset/problem/776/D

    题目大意:有n扇门及m个开关,每扇门由两个开关控制,初始状态为1(unlocked)或者0(locked)。每个开关控制xi扇门,若选择了当前开关,那么该开关所控制的所有门的状态取反(1变成0,0变成1)。问能否是所有门的状态全部为1.

    并查集

    将每个开关拆分成两个点:选择和不选择(对应x和x+m).

    每扇门对应两个开关u和v,若初始状态为1,则需要同时选择两个开关(u,v)或者同时不选择两个开关(u+m,v+m);

    若初始状态为0,则仅可以选择一个开关(u,v+m)或者(u+m,v).

    将门作为边按上面描述连接两个开关(这样保证了每扇门的最终状态均为1),形成的连通块(连通块表示被限制在一起的开关)中若同时存在x与x+m,则无解.

    代码如下:

     1 #include <cstdio>
     2 #include <iostream>
     3 #define N 100005
     4 using namespace std;
     5 int n,m,d[N],sd[N][3],f[2*N];
     6 int Find(int x){
     7     return f[x]==x?x:f[x]=Find(f[x]);
     8 }
     9 void link(int a,int b){
    10     int x=Find(a),y=Find(b);
    11     if(x!=y)f[x]=y;
    12 }
    13 int main(void){
    14     cin>>n>>m;
    15     for(int i=0;i<n;++i)cin>>d[i];
    16     for(int i=0;i<m;++i){
    17         int x;
    18         cin>>x;
    19         for(int j=0;j<x;++j){
    20             int dr;
    21             cin>>dr;dr--;
    22             sd[dr][++sd[dr][0]]=i;
    23         }
    24     }
    25     for(int i=0;i<2*m;++i)f[i]=i;
    26     for(int i=0;i<n;++i){
    27         if(d[i])link(sd[i][1],sd[i][2]),link(sd[i][1]+m,sd[i][2]+m);
    28         else link(sd[i][1],sd[i][2]+m),link(sd[i][1]+m,sd[i][2]);
    29     }
    30     for(int i=0;i<m;++i)
    31     if(Find(i)==Find(i+m)){
    32         cout<<"NO";
    33         return 0;
    34     }
    35     cout<<"YES";
    36 }
  • 相关阅读:
    css雪碧图生成工具4.3更新
    移动端webapp自适应实践(css雪碧图制作小工具实践)图文并茂
    css雪碧图生成工具4.2更新
    手机端页面rem自适应脚本
    css雪碧图生成工具4.1更新
    V4.0到来了,css雪碧图生成工具4.0更新啦
    css sprite,css雪碧图生成工具V3.0更新
    css sprite css雪碧图生成工具
    CSS3 Loading(加载)动画效果
    js new
  • 原文地址:https://www.cnblogs.com/barrier/p/6439063.html
Copyright © 2020-2023  润新知