Submission #581428

#TimeUsernameProblemLanguageResultExecution timeMemory
581428JosiaGame (IOI14_game)C++14
15 / 100
1 ms368 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);
}


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

    if (chefs[find(u)].connections.size() == 1 || chefs[find(v)].connections.size() == 1 || remaining+done < N) {
        unite(find(u), find(v));
        done++;
        return 1;
    }


    chefs[find(u)].connections.erase({u, v});
    chefs[find(v)].connections.erase({v, u});
    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...