Submission #112268

#TimeUsernameProblemLanguageResultExecution timeMemory
112268JustInCaseMeetings (JOI19_meetings)C++17
100 / 100
1121 ms191608 KiB
#include <bits/stdc++.h> #ifndef skeletaZaPrezident #include "meetings.h" #endif #define query Query #define bridge Bridge #define solve Solve #define int32_t int #define int64_t long long const int32_t MAX_N = 2000; #ifdef skeletaZaPrezident int32_t query(int32_t u, int32_t v, int32_t w) { std::cout << u << " " << v << " " << w << '\n' << std::flush; int32_t res; std::cin >> res; return res; } void bridge(int32_t u, int32_t v) { std::cout << "edge: " << u << " " << v << '\n' << std::flush; } #endif #ifndef sekeletaZaPrezident int32_t query(int32_t u, int32_t v, int32_t w); void bridge(int32_t u, int32_t v); #endif std::map< int32_t, int32_t > asked[MAX_N + 5][MAX_N + 5]; int32_t ask_query(int32_t x, int32_t y, int32_t z) { int32_t a[] = { x, y, z }; std::sort(a, a + 3); if(asked[a[0]][a[1]].count(a[2]) == 0) { asked[a[0]][a[1]][a[2]] = query(a[0], a[1], a[2]); } return asked[a[0]][a[1]][a[2]]; } struct Vertex { bool vis; int32_t subtreeSize; std::vector< int32_t > adjList; Vertex() : vis(false), subtreeSize(1) {} }; bool isInserted[MAX_N + 5]; Vertex t[MAX_N + 5]; bool sort_by_subtree_size(int32_t u, int32_t v) { return t[u].subtreeSize > t[v].subtreeSize; } void init(int32_t n) { for(int32_t i = 0; i < n; i++) { t[i].vis = false; } } void compute_subtree_sizes(int32_t v, int32_t par) { t[v].subtreeSize = 1; for(auto &x : t[v].adjList) { if(x == par || t[x].vis) { continue; } compute_subtree_sizes(x, v); t[v].subtreeSize += t[x].subtreeSize; } } int32_t find_centroid(int32_t v, int32_t par, int32_t target) { int32_t maxSubtree = -1, ind = -1; for(auto &x : t[v].adjList) { if(x == par || t[x].vis) { if(t[x].vis) { t[x].subtreeSize = 0; } continue; } if(t[x].subtreeSize > maxSubtree) { maxSubtree = t[x].subtreeSize; ind = x; } } if(ind != -1 && maxSubtree > target / 2) { return find_centroid(ind, v, target); } return v; } void solve_vertex(int32_t root, int32_t v) { compute_subtree_sizes(root, -1); int32_t centroid = find_centroid(root, -1, t[root].subtreeSize); compute_subtree_sizes(centroid, -1); int32_t aux; std::sort(t[centroid].adjList.begin(), t[centroid].adjList.end(), sort_by_subtree_size); for(int32_t i = 0; i < (int32_t) t[centroid].adjList.size(); i++) { if(i == (int32_t) t[centroid].adjList.size() - 1) { aux = ask_query(centroid, t[centroid].adjList[i], v); if(aux == v) { t[t[centroid].adjList[i]].adjList.push_back(v); t[v].adjList.push_back(t[centroid].adjList[i]); t[t[centroid].adjList[i]].adjList.erase(std::find(t[t[centroid].adjList[i]].adjList.begin(), t[t[centroid].adjList[i]].adjList.end(), centroid)); t[centroid].adjList.erase(t[centroid].adjList.begin() + i); t[centroid].adjList.push_back(v); t[v].adjList.push_back(centroid); return; } if(aux == t[centroid].adjList[i]) { t[centroid].vis = true; solve_vertex(t[centroid].adjList[i], v); return; } if(aux != centroid) { solve_vertex(aux, v); t[t[centroid].adjList[i]].adjList.push_back(aux); t[aux].adjList.push_back(t[centroid].adjList[i]); t[t[centroid].adjList[i]].adjList.erase(std::find(t[t[centroid].adjList[i]].adjList.begin(), t[t[centroid].adjList[i]].adjList.end(), centroid)); t[centroid].adjList.erase(t[centroid].adjList.begin() + i); t[centroid].adjList.push_back(aux); t[aux].adjList.push_back(centroid); isInserted[aux] = true; return; } break; } aux = ask_query(t[centroid].adjList[i], t[centroid].adjList[i + 1], v); // v is on the path from t[centroid].adjList[i] to t[centroid].adjList[i + 1] if(aux == v) { aux = ask_query(t[centroid].adjList[i], centroid, v); if(aux == centroid) { t[t[centroid].adjList[i + 1]].adjList.push_back(v); t[v].adjList.push_back(t[centroid].adjList[i + 1]); t[t[centroid].adjList[i + 1]].adjList.erase(std::find(t[t[centroid].adjList[i + 1]].adjList.begin(), t[t[centroid].adjList[i + 1]].adjList.end(), centroid)); t[centroid].adjList.erase(t[centroid].adjList.begin() + i + 1); t[centroid].adjList.push_back(v); t[v].adjList.push_back(centroid); return; } t[t[centroid].adjList[i]].adjList.push_back(v); t[v].adjList.push_back(t[centroid].adjList[i]); t[t[centroid].adjList[i]].adjList.erase(std::find(t[t[centroid].adjList[i]].adjList.begin(), t[t[centroid].adjList[i]].adjList.end(), centroid)); t[centroid].adjList.erase(t[centroid].adjList.begin() + i); t[centroid].adjList.push_back(v); t[v].adjList.push_back(centroid); return; } if(aux == t[centroid].adjList[i]) { t[centroid].vis = true; solve_vertex(t[centroid].adjList[i], v); return; } if(aux == t[centroid].adjList[i + 1]) { t[centroid].vis = true; solve_vertex(t[centroid].adjList[i + 1], v); return; } if(aux != centroid) { solve_vertex(aux, v); int32_t aux2 = ask_query(t[centroid].adjList[i], aux, centroid); if(aux2 == centroid) { t[t[centroid].adjList[i + 1]].adjList.push_back(aux); t[aux].adjList.push_back(t[centroid].adjList[i + 1]); t[t[centroid].adjList[i + 1]].adjList.erase(std::find(t[t[centroid].adjList[i + 1]].adjList.begin(), t[t[centroid].adjList[i + 1]].adjList.end(), centroid)); t[centroid].adjList.erase(t[centroid].adjList.begin() + i + 1); t[centroid].adjList.push_back(aux); t[aux].adjList.push_back(centroid); } else { t[t[centroid].adjList[i]].adjList.push_back(aux); t[aux].adjList.push_back(t[centroid].adjList[i]); t[t[centroid].adjList[i]].adjList.erase(std::find(t[t[centroid].adjList[i]].adjList.begin(), t[t[centroid].adjList[i]].adjList.end(), centroid)); t[centroid].adjList.erase(t[centroid].adjList.begin() + i); t[centroid].adjList.push_back(aux); t[aux].adjList.push_back(centroid); } isInserted[aux] = true; return; } } t[centroid].adjList.push_back(v); t[v].adjList.push_back(centroid); } void solve(int32_t n) { t[0].adjList.push_back(1); t[1].adjList.push_back(0); // solve for each node for(int32_t i = 2; i < n; i++) { if(isInserted[i]) { continue; } init(n); solve_vertex(0, i); } for(int32_t i = 0; i < n; i++) { for(auto &x : t[i].adjList) { if(x > i) { bridge(i, x); } } } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...