codeforces 468B Two Sets

来源:互联网 发布:java标识符的命名规范 编辑:程序博客网 时间:2024/04/27 21:03

题目大意:给你N个互不相同的整数,再给两个整数a,b,问能否把这N个数分成两部分,使得在a这个集合中的任一个数ai,都存在a-ai也在a 这个集合中,对b集合也同理。如果不存在一种合理分法,输出No,否则输出YES,并输出任一种合理分组。

解题思路:

1,map映射,使得查找成对的数字查找更方便。

2,虚拟出两个a,b集合的根结点n+1和n+2;

3,并查集的特殊处理;


#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <cstdlib>#include <algorithm>#include <cmath>#include <vector>#include <set>#include <list>#include <queue>#include <map>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF  0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-3#define maxn 100010#define MOD 1000000007int n,a,b,flag;int parent[100010];int num[100010];map<int,int >mp;int Find(int x){    if(x != parent[x])    {        int temp = parent[x];        parent[x] = Find(temp);    }    return parent[x];}void Union(int x,int y){    int px = Find(x);    int py = Find(y);    if(px != py)        parent[py] = px;}int main(){    int t,C = 1;    //scanf("%d",&t);    while(scanf("%d%d%d",&n,&a,&b) != EOF)    {        mp.clear();        for(int i = 1; i <= n; i++)        {            scanf("%d",&num[i]);            mp[num[i]] = i;        }        for(int i = 1; i <= n+2; i++)            parent[i] = i;        for(int i = 1; i <= n; i++)        {            if(mp[a-num[i]])                Union(i,mp[a-num[i]]);            else                Union(i,n+2);            if(mp[b-num[i]])                Union(i,mp[b-num[i]]);            else                Union(i,n+1);        }        if(Find(n+1) != Find(n+2))        {            printf("YES\n");            for(int i = 1; i <= n; i++)            {                if(Find(i) == Find(n+1))                    printf("0 ");                else                    printf("1 ");            }            printf("\n");        }        else            printf("NO\n");    }}


0 0
原创粉丝点击