Submission #206979

#TimeUsernameProblemLanguageResultExecution timeMemory
206979E869120Meetings (JOI19_meetings)C++14
100 / 100
1384 ms4088 KiB
#include "meetings.h" #include <vector> #include <map> #include <ctime> #include <algorithm> using namespace std; // 同じコードを提出して,https://oj.uz/submission/206974 では 100 点取れているんですけど, // ひどい仕打ちをやめてくれ! // おい,なめてんのか,grader の Query 関数は LCA で O(log N) で実装できるのに,なんで実装サボってんだ!!!!!! vector<int> G[2009]; vector<int> I, J1, J2; int ret1, ret2, ret3, ret4; bool passed[2009]; bool forced[2009]; map<pair<int, int>, int> Map[2009]; int Ask(int u, int v, int w) { int x[3] = { u, v, w }; sort(x, x + 3); if (Map[x[0]][make_pair(x[1], x[2])] >= 1) return Map[x[0]][make_pair(x[1], x[2])] - 1; int Z = Query(x[0], x[1], x[2]); Map[x[0]][make_pair(x[1], x[2])] = Z + 1; return Z; } void dfs(int pos) { passed[pos] = true; int cnts = 0; for (int i = 0; i < G[pos].size(); i++) { if (passed[G[pos][i]] == true) continue; dfs(G[pos][i]); cnts++; } if (cnts == 0) I.push_back(pos); } void dfs2(int pos, int to) { if (pos == to) { J2 = J1; return; } passed[pos] = true; for (int i = 0; i < G[pos].size(); i++) { if (passed[G[pos][i]] == true) continue; J1.push_back(G[pos][i]); dfs2(G[pos][i], to); J1.pop_back(); } } vector<int> getpath(int u, int v) { J1.clear(); J2.clear(); J1.push_back(u); dfs2(u, v); return J2; } int getlca(int root, vector<pair<int, int>> E) { vector<int> cand; I.clear(); for (int i = 0; i < E.size(); i++) cand.push_back(E[i].first); for (int i = 0; i < E.size(); i++) cand.push_back(E[i].second); for (int i : cand) G[i].clear(); for (int i : cand) passed[i] = false; for (int i : cand) forced[i] = false; for (int i = 0; i < E.size(); i++) { G[E[i].first].push_back(E[i].second); G[E[i].second].push_back(E[i].first); } dfs(E[0].first); if (G[E[0].first].size() == 1) I.push_back(E[0].first); int mi = I.size() / 2; for (int i = mi; i < I.size(); i++) { int R = Ask(root, I[i - mi], I[i]); ret3++; for (int j : cand) passed[j] = false; vector<int> C1 = getpath(I[i - mi], R); for (int j = 0; j < C1.size() - 1; j++) forced[C1[j]] = true; for (int j : cand) passed[j] = false; vector<int> C2 = getpath(I[i], R); for (int j = 0; j < C2.size() - 1; j++) forced[C2[j]] = true; } for (int i : cand) { if (forced[i] == false) return i; } return -1; } vector<pair<int, int>> dfs(vector<int> A) { if (A.size() == 1) { return vector<pair<int, int>>{}; } if (A.size() == 2) { return vector<pair<int, int>>{make_pair(A[0], A[1])}; } if (A.size() == 3) { ret4++; int R = Ask(A[0], A[1], A[2]); vector<pair<int, int>> E; for (int i : A) { if (i != R) E.push_back(make_pair(i, R)); } return E; } if (A.size() <= 18) { vector<int> G1[24], G2[24]; for (int i = 1; i < A.size(); i++) { for (int j = i + 1; j < A.size(); j++) { int V = Ask(A[0], A[i], A[j]); ret4++; if (V == A[i]) { G1[i].push_back(j); G2[j].push_back(i); } if (V == A[j]) { G1[j].push_back(i); G2[i].push_back(j); } } } vector<int> dist(24, 0); for (int i = 0; i < A.size(); i++) { for (int j = 0; j < A.size(); j++) { for (int k : G1[j]) dist[k] = max(dist[k], dist[j] + 1); } } vector<pair<int, int>> E; for (int i = 1; i < A.size(); i++) { int s = 0; for (int j : G2[i]) { if (dist[j] == dist[i] - 1) s = j; } E.push_back(make_pair(A[i], A[s])); } return E; } // 重心っぽい頂点を見つける int grav = -1; while (true) { int s = rand() % A.size(), cnt = 0; bool flag = false; for (int i = 1; i <= 6; i++) { int t = -1, u = -1; while (A[s] == t || t == u || A[s] == u) { t = A[rand() % A.size()]; u = A[rand() % A.size()]; } ret1++; if (Ask(A[s], t, u) == A[s]) cnt++; if (i == 1 && cnt <= 0) { flag = true; break; } if (i == 3 && cnt <= 1) { flag = true; break; } if (i == 6 && cnt <= 2) { flag = true; break; } //if (i == 8 && cnt <= 3) { flag = true; break; } } if (flag == false) { grav = s; break; } } // 重心分解をする vector<bool> used(A.size(), 0); used[grav] = true; int rem = A.size() - 1; vector<vector<int>> centroid; while (rem > 0) { int p = -1; while (p == -1 || used[p] == true) { p = rand() % A.size(); } vector<int> cand; cand.push_back(A[p]); used[p] = true; rem--; for (int i = 0; i < A.size(); i++) { if (used[i] == true || i == p) continue; ret2++; if (Ask(A[grav], A[p], A[i]) != A[grav]) { cand.push_back(A[i]); used[i] = true; rem--; } } centroid.push_back(cand); } // 復元をする vector<pair<int, int>> ans; for (vector<int> f : centroid) { vector<pair<int, int>> Z = dfs(f); for (pair<int, int> i : Z) ans.push_back(i); int U = f[0]; if (Z.size() >= 1) U = getlca(A[grav], Z); ans.push_back(make_pair(A[grav], U)); } return ans; } void Solve(int N) { vector<int> L; for (int i = 0; i < N; i++) L.push_back(i); vector<pair<int, int>> V = dfs(L); for (int i = 0; i < V.size(); i++) { if (V[i].first > V[i].second) swap(V[i].first, V[i].second); Bridge(V[i].first, V[i].second); } return; }

Compilation message (stderr)

meetings.cpp: In function 'void dfs(int)':
meetings.cpp:30:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int i = 0; i < G[pos].size(); i++) {
                  ~~^~~~~~~~~~~~~~~
meetings.cpp: In function 'void dfs2(int, int)':
meetings.cpp:40:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int i = 0; i < G[pos].size(); i++) {
                  ~~^~~~~~~~~~~~~~~
meetings.cpp: In function 'int getlca(int, std::vector<std::pair<int, int> >)':
meetings.cpp:57:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int i = 0; i < E.size(); i++) cand.push_back(E[i].first);
                  ~~^~~~~~~~~~
meetings.cpp:58:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int i = 0; i < E.size(); i++) cand.push_back(E[i].second);
                  ~~^~~~~~~~~~
meetings.cpp:63:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int i = 0; i < E.size(); i++) {
                  ~~^~~~~~~~~~
meetings.cpp:71:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int i = mi; i < I.size(); i++) {
                   ~~^~~~~~~~~~
meetings.cpp:75:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int j = 0; j < C1.size() - 1; j++) forced[C1[j]] = true;
                   ~~^~~~~~~~~~~~~~~
meetings.cpp:78:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int j = 0; j < C2.size() - 1; j++) forced[C2[j]] = true;
                   ~~^~~~~~~~~~~~~~~
meetings.cpp: In function 'std::vector<std::pair<int, int> > dfs(std::vector<int>)':
meetings.cpp:103:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int i = 1; i < A.size(); i++) {
                   ~~^~~~~~~~~~
meetings.cpp:104:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    for (int j = i + 1; j < A.size(); j++) {
                        ~~^~~~~~~~~~
meetings.cpp:111:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int i = 0; i < A.size(); i++) {
                   ~~^~~~~~~~~~
meetings.cpp:112:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    for (int j = 0; j < A.size(); j++) {
                    ~~^~~~~~~~~~
meetings.cpp:117:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int i = 1; i < A.size(); i++) {
                   ~~^~~~~~~~~~
meetings.cpp:157:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int i = 0; i < A.size(); i++) {
                   ~~^~~~~~~~~~
meetings.cpp: In function 'void Solve(int)':
meetings.cpp:183:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int i = 0; i < V.size(); i++) {
                  ~~^~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...