CF 468B Two Sets

题意:

给定n个正整数与a,b两个集合,求一种方案使得这n个数恰好被分在这两个集合中且集合中无多余的数且若x在a中则A-x在a中,若x在b中则B-x在b中。

题意理解了我好半天...

解法1:并查集。

把x, A - x,B - x(如果不存在B - x,x就不能放B集合)放入同一个并查集即可。

实现时注意一些乱七八糟的东西,大力讨论即可。

 1 #include <cstdio>
 2 #include <map>
 3 #include <cstring>
 4 const int N = 100010;
 5 
 6 int a[N], ans[N], A, B, n, fa[N];
 7 std::map<int, int> mp;
 8 
 9 inline int find(int x) {
10     if(x == fa[x]) {
11         return x;
12     }
13     return fa[x] = find(fa[x]);
14 }
15 inline bool check(int x, int y) {
16     return find(x) == find(y);
17 }
18 inline void merge(int x, int y) {
19     fa[find(x)] = find(y);
20     return;
21 }
22 
23 
24 int main() {
25     memset(ans, -1, sizeof(ans));
26     for(int i = 1; i < N; i++) {
27         fa[i] = i;
28     }
29     scanf("%d%d%d", &n, &A, &B);
30     for(int i = 1; i <= n; i++) {
31         scanf("%d", &a[i]);
32         mp[a[i]] = i;
33     }
34     for(int i = 1; i <= n; i++) {
35         bool x = mp.find(A - a[i]) == mp.end();
36         bool y = mp.find(B - a[i]) == mp.end();
37         if(x && y) {
38             printf("NO");
39             return 0;
40         }
41         else if(x) {
42             int &t = ans[mp[B - a[i]]];
43             if(t == 0) {
44                 printf("NO");
45                 return 0;
46             }
47             if(t == -1) {
48                 t = 1;
49             }
50             ans[i] = 1;
51             merge(i, mp[B - a[i]]);
52         }
53         else if(y) {
54             int &t = ans[mp[A - a[i]]];
55             if(t == 1) {
56                 printf("NO");
57                 return 0;
58             }
59             if(t == -1) {
60                 t = 0;
61             }
62             ans[i] = 0;
63             merge(i, mp[A - a[i]]);
64         }
65         else {
66            merge(i, mp[A - a[i]]);
67            merge(i, mp[B - a[i]]);
68         }
69     }
70 
71     for(int i = 1; i <= n; i++) {
72         if(ans[i] == -1) {
73             ans[i] = ans[find(i)];
74         }
75         else {
76             if(ans[find(i)] == -1) {
77                 ans[find(i)] = ans[i];
78             }
79             else if(ans[find(i)] != ans[i]) {
80                 printf("NO");
81                 return 0;
82             }
83         }
84     }
85     printf("YES
");
86     for(int i = 1; i <= n; i++) {
87         if(ans[find(i)] == -1) {
88             printf("0 ");
89         }
90         else {
91             printf("%d ", ans[find(i)]);
92         }
93     }
94 
95     return 0;
96 }
AC代码
原文地址:https://www.cnblogs.com/huyufeifei/p/9390391.html