Submission #1369456

#TimeUsernameProblemLanguageResultExecution timeMemory
1369456cnam9Friends (BOI17_friends)C++20
100 / 100
950 ms21012 KiB
#include <iostream>
#include <vector>
#include <algorithm>
#pragma GCC optimize("O3")

using namespace std;

constexpr int N = 2500;
constexpr int K = 15;
constexpr double MAX_TIME = 0.95;
constexpr clock_t DEADLINE = MAX_TIME * CLOCKS_PER_SEC;

int n, s, p, q;
vector<int> graph[N];
bool adj[N][N];

template <class T, size_t N>
class BufferedVector {
    T buf[N];
    int sz = 0;

public:
    void clear() { sz = 0; }
    int size() { return sz; }

    void push_back(T value) { buf[sz++] = value; }
    void pop_back() { --sz; }

    int *begin() { return buf; }
    int *end() { return buf + sz; }
};

template <class T, size_t N>
struct BufferedQueue {
    T buf[N];
    int l = 0, r = 0;

    void clear() { l = r = 0; }
    int size() const { return r - l; }
    bool empty() const { return r == l; }

    int *begin() { return buf + l; }
    int *end() { return buf + r; }

    void push(T value) { buf[r++] = value; }
    T pop() { return buf[l++]; }
    void unpush() { --r; }
    T unpop() { --l; }

    T &operator[](const int i) { return buf[i]; }
    const T &operator[](const int i) const { return buf[i]; }
};

bool visited[N + 1];
bool done;

struct Group {
    int size;
    int visited[N];
    BufferedQueue<int, N> to_visit;
    int outdegree;
    int indegree[N];
};
Group groups[N];

void find_group(int);
void find_groups(int);

void find_group(int g) {
    if (clock() > DEADLINE) {
        cout << "detention";
        exit(0);
    }
    Group &group = groups[g];

    if (group.size < p) {
        int l = group.to_visit.l;

        while (!group.to_visit.empty()) {
            int u = group.to_visit.pop();
            if (group.visited[u] < 0) {
                group.visited[u]--;
                continue;
            }

            visited[u] = true;
            group.size++;
            group.visited[u] = 1;
            group.outdegree -= group.indegree[u];

            for (int v : graph[u]) {
                if (group.visited[v] > 0) continue;
                group.outdegree++;
                if (group.visited[v] || visited[v]) continue;

                if (group.indegree[v]++ == 0) {
                    group.to_visit.push(v);
                }
            }

            find_group(g);
            if (done) return;

            for (int v : graph[u]) {
                if (group.visited[v] > 0) continue;
                group.outdegree--;
                if (group.visited[v] || visited[v]) continue;

                if (--group.indegree[v] == 0) {
                    group.to_visit.unpush();
                }
            }

            visited[u] = false;
            group.size--;
            group.visited[u] = -1;
            group.outdegree += group.indegree[u];
        }

        group.to_visit.l = l;
        for (int i = l; i < group.to_visit.r; i++) {
            int u = group.to_visit[i];
            group.visited[u]++;
        }
    }

    if (group.size && group.outdegree <= q) {
        find_groups(g + 1);
    }
}

void find_groups(int g) {
    int u = 0;
    while (visited[u]) u++;
    if (u == n) {
        cout << "home\n";
        cout << g << '\n';
        done = true;
        return;
    }
    // cout << "find_groups " << g << ' ' << u << endl;

    Group &group = groups[g];
    group.to_visit.push(u);

    find_group(g);

    if (done) {
        cout << group.size;
        for (int u = 0; u < n; u++) {
            if (group.visited[u] > 0)
                cout << ' ' << u;
        }
        cout << '\n';
        return;
    }

    group.to_visit.clear();
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    // freopen("input.txt", "r", stdin);

    cin >> n >> p >> q;

    if (n == 0) {
        cout << "home\n0";
        return 0;
    }
    if (p == 0) {
        cout << "detention";
        return 0;
    }

    for (int u = 0; u < n; u++) {
        int deg;
        cin >> deg;

        graph[u].resize(deg);

        for (int &v : graph[u]) {
            cin >> v;
            adj[u][v] = 1;
        }
        sort(graph[u].begin(), graph[u].end());
    }

    for (int u = 0; u < n; u++) {
        if (graph[u].size() >= p + q) {
            cout << "detention";
            return 0;
        }
        for (int v : graph[u]) {
            if (!adj[v][u]) {
                cout << "detention";
                return 0;
            }
        }
    }

    find_groups(0);
    if (!done) {
        cout << "detention";
    }

    return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...