• 集合问题(并查集)


    链接:https://www.nowcoder.com/acm/contest/77/D
    来源:牛客网

    集合问题
    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 262144K,其他语言524288K
    64bit IO Format: %lld

    题目描述

    给你a,b和n个数p[i],问你如何分配这n个数给A,B集合,并且满足:

    若x在集合A中,则a-x必须也在集合A中。

    若x在集合B中,则b-x必须也在集合B中。

    输入描述:

    第一行 三个数 n a b  1<=n<=1e5  1<=a,b<=1e9
    第二行 n个数 p1 p2 p3...pn 1<=pi<=1e9

    输出描述:

    如果可以恰好分开就输出第一行 YES
    然后第二行输出 n个数 分别代表pi 是哪个集合的 0 代表是A集合 1代表是B 集合
    不行就输出NO
    放在哪个集合都可以的时候优先放B
    示例1

    输入

    4 5 9
    2 3 4 5

    输出

    YES
    0 0 1 1
    示例2

    输入

    3 3 4
    1 2 4

    输出

    NO

     1 #include <iostream>
     2 #include <cstring>
     3 #include <string>
     4 #include <algorithm>
     5 #include <cstdio>
     6 #include <map>
     7 using namespace std;
     8 
     9 const int maxn = 1e5 + 7;
    10 int n, A, B, fa[maxn], a[maxn];
    11 map<int, int>mp;
    12 void init() {
    13     for (int i = 0; i <= n + 1; i++)
    14         fa[i] = i;
    15 }
    16 int find(int x)
    17 {
    18     if (fa[x] == x)return x;
    19     else return fa[x] = find(fa[x]);
    20 }
    21 void uni(int x, int y)
    22 {
    23     int px = find(x);
    24     int py = find(y);
    25     if (px == py)return;
    26     else fa[px] = py;
    27 }
    28 int main() 
    29 {
    30     scanf("%d%d%d", &n, &A, &B);
    31     int max1 = 0;
    32     for (int i = 1; i <= n; i++)
    33     {
    34         scanf("%d", &a[i]);
    35         mp[a[i]] = i;
    36         max1 = max(max1, a[i]);
    37     }
    38     if (max1 >= max(A, B))
    39     {
    40         return printf("NO
    "), 0;
    41     }
    42     else
    43     {
    44         init();
    45         for (int i = 1; i <= n; i++)
    46         {
    47             if (mp[B - a[i]])//如果B-a[i]存在
    48                 uni(i, mp[B - a[i]]);//就把(B-a[i])数的序号和i合并在一起
    49             else uni(i, 0);//否则放到和0一个集合(a)里去
    50             if (mp[A - a[i]])
    51                 uni(i, mp[A - a[i]]);
    52             else uni(i, n + 1);
    53         }
    54         int af = find(0);
    55         int bf = find(n + 1);
    56         if (af == bf)//一个数两个集合里都必须有,产生矛盾
    57         {
    58             return printf("NO
    "), 0;
    59         }
    60         else
    61         {
    62             printf("YES
    ");
    63             for (int i = 1; i <= n; i++)
    64             {
    65                 if (i != 1)printf(" ");
    66                 if (af == find(i))printf("0");
    67                 else printf("1");
    68             }
    69             printf("
    ");
    70         }
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    Noe4j启动警告
    SpringBoot
    MySQL数据库 java SQL语句区分大小写分析
    day24 模块的语法
    day23 re模块
    day22 常用模块02 序列化
    day21 常用模块01
    day20 面向对象06 MRO和C3算法
    day19 面向对象05 约束
    day18 面向对象04 反射
  • 原文地址:https://www.cnblogs.com/caiyishuai/p/13271166.html
Copyright © 2020-2023  润新知