Submission #286451

#TimeUsernameProblemLanguageResultExecution timeMemory
286451stoyan_malininSimurgh (IOI17_simurgh)C++14
30 / 100
3080 ms6128 KiB
#include "simurgh.h" //#include "grader.cpp" #include <set> #include <random> #include <vector> #include <assert.h> #include <iostream> #include <algorithm> using namespace std; const int MAXN = 250; mt19937 rnd(22); int ASKED = 0; struct DSU { int parent[MAXN*MAXN]; int color[MAXN*MAXN]; DSU(){} DSU(int n) { for(int i = 0;i<=n;i++) { this->parent[i] = i; this->color[i] = -1; } } void reset(int n) { for(int i = 0;i<=n;i++) { this->parent[i] = i; this->color[i] = -1; } } int Find(int x) { if(parent[x]==x) return x; parent[x] = Find(parent[x]); return parent[x]; } bool UnionSimple(int u, int v) { u = Find(u); v = Find(v); if(u==v) return false; parent[v] = u; return true; } bool UnionFull(int u, int v) { u = Find(u); v = Find(v); if(u==v) return false; int newColor = max(color[u], color[v]); color[u] = newColor; color[v] = newColor; parent[v] = u; return true; } int getColor(int x) { return color[Find(x)]; } void colorize(int x, int col) { x = Find(x); color[x] = col; } }; DSU relationKeeper; int n; vector <pair <int, int>> edges; DSU T; vector <int> inds; vector <int> constructST() { T.reset(n); vector <int> ST; for(int i: inds) { if(relationKeeper.getColor(i)==1) { T.UnionSimple(edges[i].first, edges[i].second); ST.push_back(i); } } for(int i: inds) { if(relationKeeper.getColor(i)!=0 && T.UnionSimple(edges[i].first, edges[i].second)==true) { ST.push_back(i); } } return ST; } int askVector(vector <int> v) { ASKED++; if(ASKED==30*1000) assert(false); return count_common_roads(v); } int askSet(set <int> s) { ASKED++; if(ASKED==30*1000) assert(false); vector <int> v; for(int x: s) v.push_back(x); return count_common_roads(v); } vector <int> getReplacements(vector <int> &ST, int e) { T.reset(n); for(int edgeInd: ST) if(edgeInd!=e) T.UnionSimple(edges[edgeInd].first, edges[edgeInd].second); vector <int> out; for(int i = 0;i<edges.size();i++) { if(i==e) continue; if(T.Find(edges[i].first)==T.Find(edges[i].second)) continue; out.push_back(i); if(relationKeeper.getColor(i)!=-1) break; } return out; } int getDiff(vector <int> &ST, int e1, int e2, int base) { ST.push_back(e2); int res = askVector(ST); ST.pop_back(); if(base==res) return 0; if(base<res) return 1; if(base>res) return 2; } void processDif(int e1, int e2, int diff) { if(diff==0) { relationKeeper.UnionFull(e1, e2); } else if(diff==1) { relationKeeper.colorize(e1, 0); relationKeeper.colorize(e2, 1); } else if(diff==2) { relationKeeper.colorize(e1, 1); relationKeeper.colorize(e2, 0); } } vector <int> set2Vector(set <int> s) { vector <int> out; for(int x: s) out.push_back(x); return out; } vector<int> find_roads(int N, vector<int> U, vector<int> V) { n = N; for(int i = 0;i<U.size();i++) edges.push_back({U[i], V[i]}); relationKeeper = DSU(edges.size()); for(int i = 0;i<edges.size();i++) inds.push_back(i); for(int iter = 0;iter<=n*n/2;iter++) { shuffle(inds.begin(), inds.end(), rnd); vector <int> ST = constructST(); //cout << "currST: "; //for(int x: ST) cout << " " << x; //cout << '\n'; int royalCnt = askVector(ST); if(royalCnt==n-1) return ST; int e = -1; for(int i = 0;i<ST.size();i++) { if(relationKeeper.getColor(ST[i])==-1) { e = ST[i]; ST.erase(ST.begin()+i); break; } } //if(e==-1) return {}; //cout << " --- " << e << " --- " << '\n'; vector <int> replacements = getReplacements(ST, e); //cout << "replacements:"; //for(int x: replacements) cout << " " << x; //cout << '\n'; for(int edgeInd: replacements) { if(relationKeeper.getColor(edgeInd)!=-1) { int diff = getDiff(ST, e, edgeInd, royalCnt); processDif(e, edgeInd, diff); break; } } if(relationKeeper.getColor(e)==-1) { for(int edgeInd: replacements) { //if(edgeInd==e) return {}; //if(!(edgeInd>=0 && edgeInd<edges.size())) return {}; int diff = getDiff(ST, e, edgeInd, royalCnt); processDif(e, edgeInd, diff); } if(relationKeeper.getColor(e)==-1) { relationKeeper.colorize(e, 1); for(int edgeInd: replacements) relationKeeper.colorize(edgeInd, 1); } } //cout << "color of " << e << " is " << relationKeeper.getColor(e) << '\n'; } return {}; } /* 4 6 0 1 0 2 0 3 1 2 1 3 2 3 0 1 5 */

Compilation message (stderr)

simurgh.cpp: In function 'std::vector<int> getReplacements(std::vector<int>&, int)':
simurgh.cpp:146:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  146 |     for(int i = 0;i<edges.size();i++)
      |                   ~^~~~~~~~~~~~~
simurgh.cpp: In function 'std::vector<int> find_roads(int, std::vector<int>, std::vector<int>)':
simurgh.cpp:198:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  198 |     for(int i = 0;i<U.size();i++) edges.push_back({U[i], V[i]});
      |                   ~^~~~~~~~~
simurgh.cpp:201:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  201 |     for(int i = 0;i<edges.size();i++)
      |                   ~^~~~~~~~~~~~~
simurgh.cpp:217:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  217 |         for(int i = 0;i<ST.size();i++)
      |                       ~^~~~~~~~~~
simurgh.cpp: In function 'int getDiff(std::vector<int>&, int, int, int)':
simurgh.cpp:167:1: warning: control reaches end of non-void function [-Wreturn-type]
  167 | }
      | ^
#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...