#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int N, P, Q;
cin >> N >> P >> Q;
const auto Impossible = [&]() {
cout << "detention\n";
exit(0);
};
vector<vector<int>> adj(N);
vector<vector<int>> mat(N, vector<int>(N));
for (int i = 0; i < N; i++) {
int p;
cin >> p;
while (p--) {
int j;
cin >> j;
mat[i][j] = 1;
adj[i].emplace_back(j);
}
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (mat[i][j] != mat[j][i]) {
Impossible();
}
}
}
// Solution:
// Consider finding a group for a node u. For every node v
// not adjacent to u, we don't need to consider them (since
// it will only increase Q unnecessarily). For every node v
// adjacent to u, either we pick v (and increase current p)
// or we don't pick v (and increase current q). This way,
// we have around 2^{P + Q} total options.
//
// We find a group for every node u. This runs in O(N (P + Q) 2^{P + Q}).
// Then, for every pair of nodes, consider the 2 groups of these
// nodes. If they arent' disjoint, we want to split them so they
// are. We can note that:
//
// p1, p2 <= P, q1, q2 <= Q
// Let p3 = intersection of (p1, p2).
// Then:
// q1 + edges[p1][p3] <= Q
// q2 + edges[p3][p2] <= Q.
// So, min(q1 + edges[p3][p2], q2 + edges[p1][p3]) <= Q.
//
// So, we can always split them into disjoint groups. We repair
// all groups this way in O(N^2 * (P + Q)).
//
// Time complexity: O(N * (P + Q) * (N + 2^{P + Q})).
vector<int> cur;
vector<int> state;
const auto GetGroup = [&](const auto &self, int cur_head, int ptr, int p, int q, vector<int> &res) {
if (!res.empty()) return;
if (p > P || q > Q) return;
if (cur_head == p) { // found group
res = cur;
return;
}
int u = cur[cur_head];
if (adj[u].size() == ptr) {
return self(self, cur_head + 1, 0, p, q, res);
}
int v = adj[u][ptr];
if (state[v] == 0) { // v is undecided
state[v] = -1;
self(self, cur_head, ptr + 1, p, q + 1, res);
state[v] = +1;
cur.emplace_back(v);
self(self, cur_head, ptr + 1, p + 1, q, res);
cur.pop_back();
state[v] = 0;
} else if (state[v] == -1) { // we already decided not to pick this node
return self(self, cur_head, ptr + 1, p, q + 1, res);
} else if (state[v] == +1) { // we already picked this node in group
return self(self, cur_head, ptr + 1, p, q, res);
}
};
vector<vector<int>> inGroup(N);
for (int u = 0; u < N; u++) {
state.assign(N, 0);
cur = {u};
state[u] = 1;
GetGroup(GetGroup, 0, 0, 1, 0, inGroup[u]);
if (inGroup[u].empty()) {
Impossible();
}
}
const auto IsValid = [&](const vector<int> &A) {
if (A.size() > P) return false;
int q = 0;
static vector<int> in(N);
for (auto i : A) in[i] = 1;
for (auto i : A) for (auto j : adj[i]) if (!in[j]) q++;
for (auto i : A) in[i] = 0;
return q <= Q;
};
const auto FixGroup = [&](int x, int y) {
static vector<int> who(N);
for (auto i : inGroup[x]) who[i] = 0;
for (auto i : inGroup[y]) who[i] = 0;
for (auto i : inGroup[x]) who[i] |= 1;
for (auto i : inGroup[y]) who[i] |= 2;
vector<int> xA, yA;
vector<int> xB, yB;
for (auto i : inGroup[x]) {
if (who[i] == 1) {
xA.emplace_back(i);
xB.emplace_back(i);
} else {
xA.emplace_back(i);
}
}
for (auto i : inGroup[y]) {
if (who[i] == 2) {
yA.emplace_back(i);
yB.emplace_back(i);
} else {
yA.emplace_back(i);
}
}
if (IsValid(xA) && IsValid(yB)) {
inGroup[x] = xA;
inGroup[y] = yB;
} else if (IsValid(xB) && IsValid(yA)) {
inGroup[x] = xB;
inGroup[y] = yA;
} else {
return false;
}
return true;
};
state.assign(N, 0);
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
assert(FixGroup(i, j));
}
}
vector<vector<int>> answer;
for (int i = 0; i < N; i++) {
if (!inGroup[i].empty()) {
answer.emplace_back(inGroup[i]);
}
}
cout << "home\n";
cout << answer.size() << '\n';
for (auto &a : answer) {
sort(begin(a), end(a));
cout << a.size();
for (auto i : a) cout << ' ' << i;
cout << '\n';
}
return 0;
}
Compilation message
friends.cpp: In instantiation of 'main()::<lambda(const auto:23&, int, int, int, int, std::vector<int>&)> [with auto:23 = main()::<lambda(const auto:23&, int, int, int, int, std::vector<int>&)>]':
friends.cpp:99:46: required from here
friends.cpp:74:23: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
74 | if (adj[u].size() == ptr) {
| ~~~~~~~~~~~~~~^~~~~~
friends.cpp: In lambda function:
friends.cpp:106:18: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
106 | if (A.size() > P) return false;
| ~~~~~~~~~^~~
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1 ms |
204 KB |
Output is correct |
2 |
Correct |
1 ms |
204 KB |
Output is correct |
3 |
Correct |
1 ms |
204 KB |
Output is correct |
4 |
Correct |
1 ms |
204 KB |
Output is correct |
5 |
Correct |
1 ms |
204 KB |
Output is correct |
6 |
Correct |
1 ms |
316 KB |
Output is correct |
7 |
Correct |
1 ms |
204 KB |
Output is correct |
8 |
Correct |
1 ms |
204 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1 ms |
204 KB |
Output is correct |
2 |
Correct |
13 ms |
512 KB |
Output is correct |
3 |
Correct |
6 ms |
332 KB |
Output is correct |
4 |
Correct |
1 ms |
588 KB |
Output is correct |
5 |
Correct |
2 ms |
588 KB |
Output is correct |
6 |
Correct |
1 ms |
460 KB |
Output is correct |
7 |
Correct |
3 ms |
332 KB |
Output is correct |
8 |
Correct |
23 ms |
588 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1 ms |
204 KB |
Output is correct |
2 |
Correct |
13 ms |
512 KB |
Output is correct |
3 |
Correct |
6 ms |
332 KB |
Output is correct |
4 |
Correct |
1 ms |
588 KB |
Output is correct |
5 |
Correct |
2 ms |
588 KB |
Output is correct |
6 |
Correct |
1 ms |
460 KB |
Output is correct |
7 |
Correct |
3 ms |
332 KB |
Output is correct |
8 |
Correct |
23 ms |
588 KB |
Output is correct |
9 |
Correct |
1 ms |
204 KB |
Output is correct |
10 |
Correct |
361 ms |
4460 KB |
Output is correct |
11 |
Correct |
442 ms |
6676 KB |
Output is correct |
12 |
Correct |
482 ms |
6216 KB |
Output is correct |
13 |
Correct |
555 ms |
6724 KB |
Output is correct |
14 |
Correct |
31 ms |
13252 KB |
Output is correct |
15 |
Correct |
30 ms |
13132 KB |
Output is correct |
16 |
Correct |
9 ms |
16144 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1 ms |
204 KB |
Output is correct |
2 |
Correct |
1 ms |
204 KB |
Output is correct |
3 |
Correct |
1 ms |
204 KB |
Output is correct |
4 |
Correct |
1 ms |
204 KB |
Output is correct |
5 |
Correct |
1 ms |
204 KB |
Output is correct |
6 |
Correct |
1 ms |
316 KB |
Output is correct |
7 |
Correct |
1 ms |
204 KB |
Output is correct |
8 |
Correct |
1 ms |
204 KB |
Output is correct |
9 |
Correct |
1 ms |
204 KB |
Output is correct |
10 |
Correct |
13 ms |
512 KB |
Output is correct |
11 |
Correct |
6 ms |
332 KB |
Output is correct |
12 |
Correct |
1 ms |
588 KB |
Output is correct |
13 |
Correct |
2 ms |
588 KB |
Output is correct |
14 |
Correct |
1 ms |
460 KB |
Output is correct |
15 |
Correct |
3 ms |
332 KB |
Output is correct |
16 |
Correct |
23 ms |
588 KB |
Output is correct |
17 |
Correct |
1 ms |
204 KB |
Output is correct |
18 |
Correct |
361 ms |
4460 KB |
Output is correct |
19 |
Correct |
442 ms |
6676 KB |
Output is correct |
20 |
Correct |
482 ms |
6216 KB |
Output is correct |
21 |
Correct |
555 ms |
6724 KB |
Output is correct |
22 |
Correct |
31 ms |
13252 KB |
Output is correct |
23 |
Correct |
30 ms |
13132 KB |
Output is correct |
24 |
Correct |
9 ms |
16144 KB |
Output is correct |
25 |
Correct |
1 ms |
204 KB |
Output is correct |
26 |
Correct |
543 ms |
14872 KB |
Output is correct |
27 |
Correct |
457 ms |
13432 KB |
Output is correct |
28 |
Correct |
505 ms |
11336 KB |
Output is correct |
29 |
Correct |
20 ms |
4824 KB |
Output is correct |
30 |
Correct |
16 ms |
7104 KB |
Output is correct |
31 |
Correct |
12 ms |
7084 KB |
Output is correct |
32 |
Correct |
9 ms |
16172 KB |
Output is correct |
33 |
Execution timed out |
1083 ms |
25248 KB |
Time limit exceeded |
34 |
Halted |
0 ms |
0 KB |
- |