牛客-2018多校算法第五场D-集合问题+并查集

集合问题

题意:

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

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

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

思路:并查集操作,自己主要是没想到用map去映射1e9-->1e5;

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdio>
#include <map>
using namespace std;

const int maxn = 1e5+7;
int n,A,B,fa[maxn],a[maxn];
map<int,int>mp;
void init(){
    for(int i=0;i<=n+1;i++)
        fa[i]=i;
}
int find(int x)
{
    if(fa[x]==x)return x;
    else return fa[x] = find(fa[x]);
}
void uni(int x,int y)
{
    int px = find(x);
    int py = find(y);
    if(px==py)return;
    else fa[px] = py;
}
int main(){
    scanf("%d%d%d",&n,&A,&B);
    int max1 = 0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        mp[a[i]] = i;
        max1 =max(max1,a[i]); 
    }
    if(max1>=max(A,B))
        {return printf("NO
"),0;}
    else 
        {
            init();
            for(int i=1;i<=n;i++)
            {
                if(mp[B-a[i]])
                    uni(i,mp[B-a[i]]);
                else uni(i,0);
                if(mp[A-a[i]])
                    uni(i,mp[A-a[i]]);
                else uni(i,n+1);
            }
            int af = find(0);
            int bf = find(n+1);
            if(af==bf)
            {
                return printf("NO
"),0;
            }
            else 
            {
                printf("YES
");
                for(int i=1;i<=n;i++)
                {
                    if(i!=1)printf(" ");
                    if(af==find(i))printf("0");
                    else printf("1");
                }
                printf("
");
            }
        }
    return 0;
}
原文地址:https://www.cnblogs.com/ckxkexing/p/8474566.html