Submission #931554

#TimeUsernameProblemLanguageResultExecution timeMemory
931554nguyentunglamSimurgh (IOI17_simurgh)C++17
0 / 100
1 ms348 KiB
#include<bits/stdc++.h> #include "simurgh.h" using namespace std; const int N = 510 + 10; struct DSU { vector<int> lab; void init (int sz) { lab.resize(sz + 2); for(int i = 0; i <= sz; i++) lab[i] = -1; } int root(int v) { return lab[v] < 0 ? v : lab[v] = root(lab[v]); } bool join(int u, int v) { u = root(u); v = root(v); if (u == v) return false; if (lab[u] > lab[v]) swap(u, v); lab[u] += lab[v]; lab[v] = u; return true; } }; DSU edge; DSU tree[N]; vector<int> adj[N], _adj[N], st, arr[N]; int h[N], par[N], __u[N], __v[N]; bool in[N], taken[N], vis[N], royal[N]; int idx[N], know[N]; void dfs(int u, int p) { h[u] = h[p] + 1; par[u] = p; for(int &v : adj[u]) if (v != p) dfs(v, u); } void tell (int u) { vis[u] = 1; for(int &v : _adj[u]) if (know[v] == -1) { know[v] = know[u]; tell(v); } } int calc (vector<int> a) { DSU tmp; tmp.init(st.size() + 2); vector<int> ask = a; for(int &j : a) assert(tmp.join(__u[j], __v[j])); int sum = 0; for(int &j : st) if (tmp.join(__u[j], __v[j])) { ask.push_back(j); sum += royal[j]; } assert(ask.size() == st.size()); return count_common_roads(ask) - sum; } void solve(vector<int> cur, int tmp) { if (!tmp) return; // for(auto &j : cur) cout << j << " "; cout << tmp << "@@" << endl; if (cur.size() == 1) { royal[cur.back()] = tmp; return; } vector<int> left, right; for(int i = 0; i < cur.size(); i++) { if (i < (int) cur.size() / 2) left.push_back(cur[i]); else right.push_back(cur[i]); } // if (left.size() >= cur.size()) { // cerr << cur.size() << endl; // } assert(left.size() < cur.size()); int cost_left = calc(left); int cost_right = tmp - cost_left; solve(left, cost_left); solve(right, cost_right); } std::vector<int> find_roads(int n, std::vector<int> u, std::vector<int> v) { int m = u.size(); edge.init(n); for(int i = 0; i < m; i++) __u[i] = u[i], __v[i] = v[i]; for(int i = 0; i <= n; i++) tree[i].init(n); for(int i = 0; i < m; i++) { if (tree[0].join(u[i], v[i])) { st.push_back(i); adj[u[i]].push_back(v[i]); adj[v[i]].push_back(u[i]); in[i] = 1; } } // for(int &j : st) cout << j << " "; cout << endl; int init = count_common_roads(st); dfs(0, 0); for(int i = 0; i < m; i++) know[i] = -1; for(int i = 0; i < m; i++) if (in[i]) { if (h[u[i]] < h[v[i]]) swap(u[i], v[i]); idx[u[i]] = i; } for(int i = 0; i < m; i++) if (!in[i]) { int x = u[i], y = v[i]; if (h[x] < h[y]) swap(x, y); vector<int> part; auto add = [&] (int a) { int _a = edge.root(a); if (!taken[_a]) { taken[_a] = 1; part.push_back(a); } }; while (h[x] > h[y]) { add(x); x = par[x]; } while (x != y) { add(x); add(y); x = par[x]; y = par[y]; } add(x); if (part.size() <= 1) continue; int know_i = -1; for(int &j : part) { taken[edge.root(j)] = 0; vector<int> ask; for(int &k : st) if (k != idx[j]) ask.push_back(k); ask.push_back(i); int tmp = count_common_roads(ask); if (tmp < init) { know[j] = 1; know_i = 0; } else if (tmp > init) { know_i = 1; know[j] = 0; } else if (know[j] != -1) { know_i = know[j]; } } int head = part[0]; for(int &j : part) edge.join(j, head); if (know_i == -1) { for(int &j : part) if (j != head) { _adj[j].push_back(head); _adj[head].push_back(j); } } else { for(int &j : part) { if (know[j] == -1) know[j] = know_i; if (!vis[j]) tell(j); } } } if (init == 0) for(int i = 0; i < n; i++) know[i] = 0; for(int i = 1; i < n; i++) { if (know[i] == -1) know[i] = 1; royal[idx[i]] = know[i]; } for(int &j : st) { cout << royal[j] << " " << u[j] << " " << v[j] << " " << j << endl; } exit(0); for(int i = 0; i < m; i++) if (!in[i]) { bool stop = 0; for(int j = 1; j <= n; j++) if (tree[j].join(u[i], v[i])) { arr[j].push_back(i); stop = 1; break; } assert(stop); } for(int j = 1; j <= n; j++) { if (!arr[j].empty()) solve(arr[j], calc(arr[j])); } for(int i = 0; i < m; i++) if (royal[i]) cout << i << " "; cout << endl; vector<int> ret; for(int i = 0; i < m; i++) if (royal[i]) ret.push_back(i); return ret; }

Compilation message (stderr)

simurgh.cpp: In function 'void solve(std::vector<int>, int)':
simurgh.cpp:79:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   79 |   for(int i = 0; i < cur.size(); i++) {
      |                  ~~^~~~~~~~~~~~
simurgh.cpp: In function 'std::vector<int> find_roads(int, std::vector<int>, std::vector<int>)':
simurgh.cpp:209:3: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
  209 |   for(int i = 0; i < m; i++) if (royal[i]) cout << i << " "; cout << endl;
      |   ^~~
simurgh.cpp:209:62: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
  209 |   for(int i = 0; i < m; i++) if (royal[i]) cout << i << " "; cout << endl;
      |                                                              ^~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...