# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
335559 | aanastasov | Connecting Supertrees (IOI20_supertrees) | C++17 | 290 ms | 22252 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>
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 && 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... |