Submission #921873

#TimeUsernameProblemLanguageResultExecution timeMemory
921873boris_mihovMeetings (JOI19_meetings)C++17
100 / 100
811 ms1412 KiB
#include "meetings.h" #include <algorithm> #include <iostream> #include <numeric> #include <cassert> #include <random> #include <vector> typedef long long llong; const int MAXN = 2000 + 10; const int INF = 1e9; int n; int sz[MAXN]; bool bl[MAXN]; int perm[MAXN]; bool alreadyAdded[MAXN]; std::vector <int> g[MAXN]; std::vector <int> c[MAXN]; std::vector <int> real[MAXN]; std::mt19937 rng(69420); void removeEdge(int u, int v) { if (u == -1 || v == -1) { return; } for (int &x : g[u]) { if (x == v) { std::swap(x, g[u].back()); g[u].pop_back(); break; } } for (int &x : g[v]) { if (x == u) { std::swap(x, g[v].back()); g[v].pop_back(); break; } } } void addEdge(int u, int v) { if (u == -1 || v == -1) { return; } g[u].push_back(v); g[v].push_back(u); } void calcSize(int node, int par) { sz[node] = 1; for (const int &u : g[node]) { if (u == par || bl[u]) { continue; } calcSize(u, node); sz[node] += sz[u]; } } int findCentroid(int node, int par, int compSz) { for (const int &u : g[node]) { if (!bl[u] && u != par && sz[u] > compSz / 2) { return findCentroid(u, node, compSz); } } return node; } int decompose(int node) { calcSize(node, -1); int cntr = findCentroid(node, -1, sz[node]); bl[cntr] = true; for (const int &u : g[cntr]) { if (bl[u]) { continue; } c[cntr].push_back(decompose(u)); real[cntr].push_back(u); } return cntr; } void search(int node, int added) { bool addedEdge = false; for (int i = 0 ; i < c[node].size() ; i += 2) { if (i == c[node].size() - 1) { int res = Query(node, real[node][i], added); if (res == node) { continue; } if (res != node && res != real[node][i] && res != added) { removeEdge(node, real[node][i]); addEdge(node, res); addEdge(res, real[node][i]); addEdge(res, added); alreadyAdded[res] = true; return; } if (res == added) { removeEdge(node, real[node][i]); if (!addedEdge) { addEdge(node, added); addedEdge = true; } addEdge(real[node][i], added); continue; } if (res == real[node][i]) { search(c[node][i], added); return; } assert(false); } int res = Query(real[node][i], real[node][i + 1], added); // std::cout << "res is: " << real[node][i] << ' ' << real[node][i + 1] << ' ' << added << " = " << res << '\n'; if (res == node) { continue; } if (res == added) { int res2 = Query(node, real[node][i], added); if (res == res2) { removeEdge(node, real[node][i]); if (!addedEdge) { addEdge(node, added); addedEdge = true; } addEdge(real[node][i], added); } else { removeEdge(node, real[node][i + 1]); if (!addedEdge) { addEdge(node, added); addedEdge = true; } addEdge(real[node][i + 1], added); } return; } if (res == real[node][i]) { search(c[node][i], added); return; } if (res == real[node][i + 1]) { search(c[node][i + 1], added); return; } if (res != node && res != real[node][i] && res != added) { int res2 = Query(node, real[node][i], added); if (res == res2) { removeEdge(node, real[node][i]); addEdge(node, res); addEdge(res, real[node][i]); addEdge(res, added); alreadyAdded[res] = true; } else { removeEdge(node, real[node][i + 1]); addEdge(node, res); addEdge(res, real[node][i + 1]); addEdge(res, added); alreadyAdded[res] = true; } return; } assert(false); } if (!addedEdge) { addEdge(node, added); } } void Solve(int N) { n = N; std::iota(perm, perm + n, 0); std::shuffle(perm, perm + n, rng); for (int i = 0 ; i < n ; ++i) { g[i].clear(); c[i].clear(); real[i].clear(); } g[perm[0]].push_back(perm[1]); g[perm[1]].push_back(perm[0]); // std::cout << "edge: " << perm[0] << ' ' << perm[1] << '\n'; for (int i = 2 ; i < n ; ++i) { // std::cout << "current: " << perm[i] << '\n'; if (alreadyAdded[perm[i]]) { continue; } for (int j = 0 ; j < n ; ++j) { c[j].clear(); real[j].clear(); std::shuffle(g[j].begin(), g[j].end(), rng); } std::fill(bl, bl + n, false); int root = decompose(perm[0]); search(root, perm[i]); } for (int i = 0 ; i < n ; ++i) { for (const int &u : g[i]) { if (i < u) { Bridge(i, u); } } } }

Compilation message (stderr)

meetings.cpp: In function 'void search(int, int)':
meetings.cpp:113:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  113 |     for (int i = 0 ; i < c[node].size() ; i += 2)
      |                      ~~^~~~~~~~~~~~~~~~
meetings.cpp:115:15: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  115 |         if (i == c[node].size() - 1)
      |             ~~^~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...