Commit 25ce6ff9 authored by Andrew Kvapil's avatar Andrew Kvapil

Initial commit

parents
CXX=g++
CXX_FLAGS=-Wall -Wextra -pedantic -fsanitize=address
.PHONY: run test clean
exe: main.cpp
$(CXX) $(CXX_FLAGS) main.cpp -o exe
run: exe
./exe
clean:
rm -f ./exe
test: exe
for file in test*; do ./exe < $$file; done;
#include <iostream>
using namespace std;
//typedef int_fast8_t i8;
typedef signed short i8;
struct Node {
bool has_parent = false;
size_t children_size;
size_t n_children;
Node** children;
int index;
i8 value;
i8 goal;
};
void add_child(Node& root, Node* child) {
if (root.n_children >= root.children_size) {
root.children_size += root.children_size / 2;
Node** resized = new Node*[root.children_size];
for (unsigned int i = 0; i < root.n_children; i++) {
resized[i] = root.children[i];
}
delete[] root.children;
root.children = resized;
}
child->has_parent = true;
root.children[root.n_children++] = child;
}
Node* new_node(i8 value) {
Node* result = new Node();
result->children_size = 2;
result->children = new Node*[2];
result->n_children = 0;
result->value = value;
return result;
}
void load_input(Node*** nodes, Node& root, int& n) {
cin >> n;
*nodes = new Node*[n];
for (int i = 0; i < n; i++) {
(*nodes)[i] = new_node(0);
(*nodes)[i]->index = i;
}
//cout << "Dear Evan Hansen," << endl;
for (int i = 0; i < n - 1; i++) {
int u, v;
cin >> u >> v;
if (u > v) {
int tmp = u;
u = v;
v = tmp;
}
add_child(*(*nodes)[u - 1], (*nodes)[v - 1]);
}
//cout << "today is gonna be a good day," << endl;
for (int i = 0; i < n; i++) {
i8 init;
cin >> init;
(*nodes)[i]->value = init;
}
//cout << "and here's why:" << endl;
for (int i = 0; i < n; i++) {
i8 goal;
cin >> goal;
(*nodes)[i]->goal = goal;
}
for (int i = 0; i < n; i++) {
if (!(*nodes)[i]->has_parent) {
root = *(*nodes)[i];
break;
}
}
}
void print_tree(Node& root) {
cout << "{ " << root.value << "; children = [";
for (unsigned int i = 0; i < root.n_children; i++) {
print_tree(*(root.children[i]));
}
cout << "]; }";
}
void add_step(Node& root, int** steps, int& steps_size, int& n_steps) {
if (n_steps >= steps_size - 1) {
steps_size += steps_size / 2;
int* resized = new int[steps_size];
for (int i = 0; i < n_steps; i++) {
resized[i] = (*steps)[i];
}
delete[] *steps;
*steps = resized;
}
(*steps)[n_steps++] = root.index;
}
void xor_xor_xoooor(Node& root, int** steps, int& steps_size, int& n_steps, i8 n_flips = 0, i8 n_other_flips = 0) {
//cout << "processing " << root.index << ", v=" << root.value << ", g=" << root.goal << ", flips=" << (int)n_flips << endl;
if ((root.value != root.goal && n_flips == 0) || (root.value == root.goal && n_flips != 0)) {
//cout << "\tflipping!" << endl;
add_step(root, steps, steps_size, n_steps);
root.value = !root.value;
n_flips++;
}
n_flips %= 2;
cout << root.index + 1 << ": " << root.value << " " << endl;
for (unsigned int i = 0; i < root.n_children; i++) {
xor_xor_xoooor(*root.children[i], steps, steps_size, n_steps, n_other_flips, n_flips);
}
}
int main() {
int* steps = new int[2];
int steps_size = 2;
int n_steps = 0;
Node** nodes;
Node root;
int n;
load_input(&nodes, root, n);
//print_tree(root);
//cout << endl;
xor_xor_xoooor(root, &steps, steps_size, n_steps);
cout << n_steps << endl;
for (int i = 0; i < n_steps; i++) {
cout << steps[i] + 1 << endl;
}
delete[] steps;
for (int i = 0; i < n; i++) {
delete[] nodes[i]->children;
delete nodes[i];
}
delete[] nodes;
return 0;
}
2
1 2
0 0
1 1
5
1 2
2 3
3 4
4 5
0 0 0 0 0
1 1 1 1 1
10
2 1
3 1
4 2
5 1
6 2
7 5
8 6
9 8
10 5
1 0 1 1 0 1 0 1 0 1
1 0 1 0 0 1 1 1 0 1
5
1 2
1 3
3 4
3 5
0 0 1 1 0
1 1 1 1 1
3
1 2
2 3
0 0 0
0 0 0
5
1 2
2 3
3 4
4 5
1 1 1 1 0
0 0 1 1 0
5
1 2
1 3
1 4
1 5
0 1 1 0 0
1 0 1 0 1
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment