제출 #981004

#제출 시각아이디문제언어결과실행 시간메모리
981004kilkuwuConnecting Supertrees (IOI20_supertrees)C++17
100 / 100
171 ms24500 KiB
#include "supertrees.h" #include <bits/stdc++.h> struct DSU { std::vector<int> e; DSU(int n) : e(n, -1) {} int find(int u) { return e[u] < 0 ? u : e[u] = find(e[u]); } bool merge(int u, int v) { u = find(u), v = find(v); if (u == v) return false; if (e[u] > e[v]) std::swap(u, v); e[u] += e[v]; e[v] = u; return true; } bool same(int u, int v) { return find(u) == find(v); } int size(int u) { return -e[find(u)]; } }; int construct(std::vector<std::vector<int>> p) { int n = p.size(); DSU dsu(n); for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (p[i][j] == 3) return false; if (p[i][j] != 0) { dsu.merge(i, j); } } } for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (!p[i][j] && dsu.same(i, j)) return false; } } // now we have all the tplt we need // now what can we do ? // each tplt has only one fucking cycle std::vector<std::vector<int>> comps(n); for (int i = 0; i < n; i++) { comps[dsu.find(i)].push_back(i); } // they must have connected to each other std::vector<std::vector<int>> b(n, std::vector<int>(n)); DSU lmao(n); std::vector<std::pair<int, int>> edges; auto add_edge = [&](int u, int v) -> void { b[u][v] = b[v][u] = 1; }; for (int c = 0; c < n; c++) { if (comps[c].empty()) continue; std::map<std::vector<int>, std::vector<int>> mp; for (int u : comps[c]) { std::vector<int> key; for (int j = 0; j < n; j++) { if (p[u][j] == 2) { key.push_back(j); } } mp[key].push_back(u); } std::vector<int> rep; for (auto& [key, val] : mp) { int total = key.size() + val.size(); if (total != (int) comps[c].size()) { return false; } for (int i = 0; i + 1 < (int) val.size(); i++) { add_edge(val[i], val[i + 1]); } rep.push_back(val[0]); } if (rep.size() == 2) { // we cannot do a cycle with two return false; } if (rep.size() > 2) { for (int i = 0; i < (int)rep.size(); i++) { add_edge(rep[i], rep[(i + 1) % rep.size()]); } } } build(b); return 1; } #ifdef LOCAL #include <vector> #include <cassert> #include <cstdio> #include <cstdlib> #include <string> static int n; static std::vector<std::vector<int>> p; static std::vector<std::vector<int>> b; static bool called = false; static void check(bool cond, std::string message) { if (!cond) { printf("%s\n", message.c_str()); fclose(stdout); exit(0); } } void build(std::vector<std::vector<int>> _b) { check(!called, "build is called more than once"); called = true; check((int)_b.size() == n, "Invalid number of rows in b"); for (int i = 0; i < n; i++) { check((int)_b[i].size() == n, "Invalid number of columns in b"); } b = _b; } int main() { assert(scanf("%d", &n) == 1); p.resize(n); for (int i = 0; i < n; i++) { p[i].resize(n); } for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { assert(scanf("%d", &p[i][j]) == 1); } } fclose(stdin); int possible = construct(p); check(possible == 0 || possible == 1, "Invalid return value of construct"); if (possible == 1) { check(called, "construct returned 1 without calling build"); } else { check(!called, "construct called build but returned 0"); } printf("%d\n", possible); if (possible == 1) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (j) { printf(" "); } printf("%d", b[i][j]); } printf("\n"); } } fclose(stdout); } #endif
#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...