Submission #581477

#TimeUsernameProblemLanguageResultExecution timeMemory
581477JosiaGame (IOI14_game)C++14
15 / 100
4 ms612 KiB
#include <bits/stdc++.h>
#include "game.h"

using namespace std;

// #define int int64_t


int N;
int done;
int remaining;

struct chefNode {
    int chef;
    set<pair<int, int>> connections;
};



vector<chefNode> chefs;

void initUnionfind(int n) {
    chefs.clear();
    chefs.resize(n);
    for (int i = 0; i<n; i++) {
        chefNode x;
        x.chef = i;
        for (int j = 0; j<n; j++) {
            if (i == j) continue;
            x.connections.insert({i, j});
        }
        chefs[i] = x;
    }
}


int find(int x) {
    if (chefs[x].chef == x) return x;
    return chefs[x].chef = find(chefs[x].chef);
}


void unite(int a, int b) {
    a = find(a); b = find(b);
    if (a == b) return;

    chefs[a].chef = b;

    for (auto i: chefs[a].connections)
        chefs[b].connections.insert(i);

    chefs[a].connections.clear();

    set<pair<int, int>> newConnections;

    for (auto i: chefs[b].connections)
        if (find(i.first) != find(i.second)) newConnections.insert(i);

    chefs[b].connections = newConnections;
}



void initialize(int n) {
    remaining = (n*(n-1))/2 +1;
    done = 0;
    N = n;
    initUnionfind(n);
}


set<pair<int, int>> connections;


int hasEdge(int u, int v) {
    remaining--;
    if (find(u) == find(v)) return 1;   // return rand()%2;

    assert(chefs[find(u)].connections.size() > 1 && chefs[find(v)].connections.size() > 1);

    chefs[find(u)].connections.erase({u, v});
    chefs[find(v)].connections.erase({v, u});

    vector<int> check = {u, v};

    while (check.size()) {
        u = check.back();
        check.pop_back();
        if (chefs[find(u)].connections.size() == 1) {
            int b = (*(chefs[find(u)].connections.begin())).second;
            unite(find(u), b);
            check.push_back(b);
        }
    }

    return 0;
}





void test(int n) {
    vector<pair<int, int>> edges;

    for (int i = 0; i<n; i++) {
        for (int j = i+1; j<n; j++) {
            edges.push_back({i, j});
        }
    }
    std::random_device rd;
    std::mt19937 g(rd());
    shuffle(edges.begin(), edges.end(), g);
    initialize(n);
    vector<int> answers;
    for (auto i: edges) {
        if (rand()%2==0) swap(i.first, i.second);
        cerr << i.first << " " << i.second << "\n";
        answers.push_back(hasEdge(i.first, i.second));
    }
    assert(answers.back() == 1);
    assert((int)accumulate(answers.begin(), answers.end(), 0) == (int)n-1);
}



// signed main() {
//     while (true) {
//         test(4);
//         // cerr << "\n";
//     }
// }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...