Codeforces 468 B Two Sets(二分図マッチング)
6926 ワード
タイトルリンク:Codeforces 468 B Two Sets
n個の数を与えて、n個の数を2つの集合の中に割り当てることを要求して、集合0の中の要素x、A-xも更に0の中で、同じ理の1の集合を要求します.
解題構想:二分図マッチングのような方法.
n個の数を与えて、n個の数を2つの集合の中に割り当てることを要求して、集合0の中の要素x、A-xも更に0の中で、同じ理の1の集合を要求します.
解題構想:二分図マッチングのような方法.
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 1e5 + 5;
int N, A, B, x[maxn], v[maxn], r = 0;
map<int, int> G;
bool match (int a, int M, int k) {
int p = G[a];
if (!G.count(M - a))
return false;
int q = G[M - a];
if (v[q] == -1 || a * 2 == M) {
v[p] = v[q] = k;
} else {
if (match(A + B - 2 * M + a, M, k))
v[p] = v[q] = k;
else
return false;
}
return true;
}
bool solve () {
if (r >= max(A,B))
return false;
for (int i = 1; i <= N; i++) {
if (v[i] != -1)
continue;
if (!match(x[i], A, 0) && !match(x[i], B, 1))
return false;
}
return true;
}
int main () {
scanf("%d%d%d", &N, &A, &B);
memset(v, -1, sizeof(v));
for (int i = 1; i <= N; i++) {
scanf("%d", &x[i]);
r = max(x[i], r);
G[x[i]] = i;
}
if (solve()) {
printf("YES
");
for (int i = 1; i <= N; i++)
printf("%d%c", v[i], i == N ? '
' : ' ');
} else
printf("NO
");
return 0;
}