题意
有n个数,要分成A、B两组,要求如果x∈A则a-x∈A,如果x∈B则b-x∈B,问是否存在一种符合要求的分法
思路
并查集,先增加两个点表示A和B集合的根,对于一个数x,如果a-x存在就把x和a-x放一起,否则就将x和B的根相连,如果b-x存在就把x和b-x放一起,否则就将x和A的根相连,最后看一下A和B集合的根是否相连就可以判断出有没有解了,至于分法就看这个数是和A的根相连还是B的根相连了
#include <cstdio>
#include <map>
#include <vector>
using namespace std;
int num[100003];
int father[100003];
map<int,int> hsh;
int n,a,b,f;
int findfather(int x)
{
if(father[x]==x)
return x;
else return father[x]=findfather(father[x]);
}
int main()
{
scanf("%d%d%d",&n,&a,&b);
for(int i=1;i<=n;i++)
{
scanf("%d",&num[i]);
hsh[num[i]]=i;
}
for(int i=1;i<=n+2;i++)
father[i]=i;
for(int i=1;i<=n;i++)
{
if(hsh[a-num[i]]==0)
father[findfather(i)]=findfather(n+2);
else father[findfather(i)]=findfather(hsh[a-num[i]]);
if(hsh[b-num[i]]==0)
father[findfather(i)]=findfather(n+1);
else father[findfather(i)]=findfather(hsh[b-num[i]]);
}
if(findfather(n+1)==findfather(n+2))
printf("NO\n");
else
{
printf("YES\n");
for(int i=1;i<n;i++)
if(findfather(i)==findfather(n+1))
printf("0 ");
else printf("1 ");
if(findfather(n)==findfather(n+1))
printf("0\n");
else printf("1\n");
}
return 0;
}