# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
335558 | aanastasov | Connecting Supertrees (IOI20_supertrees) | C++17 | 312 ms | 24268 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "supertrees.h"
#include <vector>
#include <queue>
#include <iostream>
template<typename T> void debug(std::vector<T> v) {
std::cout << "{";
for (int i = 0; i < v.size(); ++i) {
if (i != 0) std::cout << ", ";
std::cout << v[i];
}
std::cout << "}" << "\n";
}
template<typename T> int count(std::vector<T>& vector, T val) {
int res = 0;
for (auto &item : vector)
if (val == item) res++;
return res;
}
int construct(std::vector<std::vector<int>> p) {
const int nodes = p.size();
auto hasEdge = std::vector<std::vector<int>>(nodes, std::vector<int>(nodes, 0));
auto marked = std::vector<bool>(nodes, false);
for (int start = 0; start < nodes; ++start) {
if (marked[start]) continue;
// Step 1: Find all the nodes in the connected component that contains <start>.
auto component = std::vector<int>();
auto q = std::queue<int>();
marked[start] = true;
q.push(start);
marked[start] = true;
while (!q.empty()) {
int src = q.front();
q.pop();
component.push_back(src);
for (int dst = 0; dst < nodes; ++dst)
if (p[src][dst] > 0 && !marked[dst]) {
marked[dst] = true;
q.push(dst);
}
}
// Step 2: Check that all nodes in the component are connected to each other,
// and that all pairs of nodes are connected by either one or two simple paths.
for (int src : component)
for (int dst : component) {
if (src != dst && p[src][dst] == 0) return 0;
if (p[src][dst] >= 3) return 0;
}
// Step 3: Divide all nodes into disjoint sets by going over only edges s.t. p[src][dst] = 1.
auto disjointSets = std::vector<std::vector<int>>();
auto visited = std::vector<bool>(nodes, false);
auto groupIndex = std::vector<int>(nodes, -1);
auto order = std::queue<int>();
for (int node : component) if (!visited[node]) {
visited[node] = true;
order.push(node);
auto group = std::vector<int>();
while (!order.empty()) {
int src = order.front();
order.pop();
groupIndex[src] = disjointSets.size();
group.push_back(src);
for (int dst : component) if (!visited[dst] && p[src][dst] == 1) {
visited[dst] = true;
order.push(dst);
}
}
for (int src : group) {
for (int dst : group)
if (src != dst && p[src][dst] != 1) return 0;
for (int dst : component) {
if (src == dst) continue;
//if (count(group, dst) == 0 && p[src][dst] != 2) return 0;
if (groupIndex[dst] != disjointSets.size() && p[src][dst] != 2) return 0;
}
}
disjointSets.push_back(group);
}
if (disjointSets.size() == 2) return 0;
// Step 4: Connect the resulting 1-tree.
for (int index = 0; index < disjointSets.size(); ++index) {
int curRepr = disjointSets[index][0];
int nextRepr = disjointSets[(index + 1) % disjointSets.size()][0];
if (disjointSets.size() > 1)
hasEdge[curRepr][nextRepr] = hasEdge[nextRepr][curRepr] = 1;
for (int j = 1; j < disjointSets[index].size(); ++j) {
int child = disjointSets[index][j];
hasEdge[curRepr][child] = hasEdge[child][curRepr] = 1;
}
}
}
build(hasEdge);
return 1;
}
Compilation message (stderr)
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |