Submission #367010

#TimeUsernameProblemLanguageResultExecution timeMemory
367010PurpleCrayonConnecting Supertrees (IOI20_supertrees)C++17
100 / 100
259 ms23788 KiB
#include "supertrees.h" #include <bits/stdc++.h> using namespace std; #define ar array #define sz(v) int(v.size()) int n; struct DSU { vector<int> p, sz; void init(int n){ sz.assign(n, 1); p.resize(n); iota(p.begin(), p.end(), 0); } int find_set(int v){ return v==p[v]?v:p[v]=find_set(p[v]); } bool union_sets(int a, int b){ if ((a=find_set(a))==(b=find_set(b))) return 0; if (sz[a] < sz[b]) swap(a, b); p[b]=a, sz[a]+=sz[b], sz[b]=0; return 1; } } d; int construct(vector<vector<int>> g) { n = sz(g); vector<vector<int>> ans(n, vector<int>(n)); bool done=0, bad=0; [&](){ //handle case with a 3 if (done || bad) return; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) if (g[i][j] == 3) { bad=1; return; } }(); [&](){ //only 1's (tree) if (done || bad) return; for (int i = 0; i < n; i++) for (int j = i+1; j < n; j++) if (g[i][j] != 1) return; for (int i = 1; i < n; i++) ans[i][0] = ans[0][i] = 1; build(ans), done=1; }(); [&](){ //0, 1's (just deal with separate comps) if (done || bad) return; for (int i = 0; i < n; i++) for (int j = i+1; j < n; j++) if (g[i][j] != 0 && g[i][j] != 1) return; d.init(n); for (int i = 0; i < n; i++) for (int j = i+1; j < n; j++) if (g[i][j]) if (d.union_sets(i, j)) ans[i][j] = ans[j][i] = 1; for (int i = 0; i < n; i++) for (int j = i+1; j < n; j++) if ((d.find_set(i) == d.find_set(j))^bool(g[i][j])) return; build(ans), done=1; }(); [&](){ //0, 2's (just deal with separate comps, put everything into cycles instead of trees) if (done || bad) return; for (int i = 0; i < n; i++) for (int j = i+1; j < n; j++) if (g[i][j] != 0 && g[i][j] != 2) return; d.init(n); for (int i = 0; i < n; i++) for (int j = i+1; j < n; j++) if (g[i][j]) d.union_sets(i, j); for (int i = 0; i < n; i++) for (int j = i+1; j < n; j++) if ((d.find_set(i) == d.find_set(j))^bool(g[i][j])) return; vector<vector<int>> comp(n); for (int i = 0; i < n; i++) comp[d.find_set(i)].push_back(i); for (int i = 0; i < n; i++) if (sz(comp[i]) > 1){ if (sz(comp[i]) == 2) return; for (int j = 0; j < sz(comp[i]); j++){ int nxt=(j+1)%sz(comp[i]); ans[comp[i][j]][comp[i][nxt]] = ans[comp[i][nxt]][comp[i][j]] = 1; } } build(ans), done=1; }(); [&](){ //full sol if (done || bad) return; d.init(n); for (int i = 0; i < n; i++) for (int j = i+1; j < n; j++) if (g[i][j]) d.union_sets(i, j); for (int i = 0; i < n; i++) for (int j = i+1; j < n; j++) if ((d.find_set(i) == d.find_set(j))^bool(g[i][j])) return; vector<vector<int>> comp(n); for (int i = 0; i < n; i++) comp[d.find_set(i)].push_back(i); d.init(n); auto solve_comp = [&](vector<int> v) -> bool { //they're all in a component for (int i : v) for (int j : v) if (i > j && g[i][j]){ if (g[i][j] == 1){ if (d.union_sets(i, j)) ans[i][j] = ans[j][i] = 1; } else if (g[i][j] == 2) { } else assert(false); } for (int i : v) for (int j : v) if (i > j && g[i][j] == 2 && d.find_set(i) == d.find_set(j)) return 0; set<int> s; for (int i : v) s.insert(d.find_set(i)); if (sz(s) == 1) return 1; else if (sz(s) == 2) return 0; vector<int> root(s.begin(), s.end()); for (int i = 0; i < sz(root); i++){ int nxt=(i+1)%(sz(root)); ans[root[i]][root[nxt]] = ans[root[nxt]][root[i]] = 1; } return 1; }; for (int i = 0; i < n; i++) if (sz(comp[i]) > 1) if (!solve_comp(comp[i])) return; build(ans), done=1; }(); return !bad && done; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...