#include using namespace std; // ifstream in("test.in"); // ofstream out("test.out"); struct Domino { int side1; int side2; }; // Global variables int n; int max_length = 1; Domino* dominos[28]; vector dominos_by_side[7]; unordered_set ignored_dominos; bool evaluate(unordered_set& ignore_candidates) { ignore_candidates.clear(); // Filled during the loop, used later unordered_set used_dominos; // Find degree of each pip int odd_vertices_count = 0; for (int i = 0; i < 7; i++) { int dominos_count = 0; for (auto it = dominos_by_side[i].begin(); it != dominos_by_side[i].end(); it++) { if (ignored_dominos.count(*it) != 1) { dominos_count++; used_dominos.insert(*it); } } // Mark as ignored candidate all dominos with pips that have odd degree if (dominos_count % 2 == 1) { odd_vertices_count++; ignore_candidates.insert(dominos_by_side[i].begin(), dominos_by_side[i].end()); } } // cout << odd_vertices_count << " odd vertices found" << endl; // Condition 1 if (odd_vertices_count > 2) { return false; } // Now evaluate using DFS here // cout << "Evaluating with DFS" << endl; unordered_set visited_dominos; visited_dominos.clear(); deque domino_queue; domino_queue.push_back(*used_dominos.begin()); visited_dominos.insert(*used_dominos.begin()); bool visited_pips[7]; for (int i = 0; i < 7; i++) { visited_pips[i] = 0; } while (domino_queue.size() > 0) { Domino* domino = domino_queue.front(); domino_queue.pop_front(); if (!visited_pips[domino->side1]) { for (auto it = dominos_by_side[domino->side1].begin(); it != dominos_by_side[domino->side1].end(); it++) { if (ignored_dominos.count(*it) == 1) { continue; } if (visited_dominos.count(*it) == 0) { visited_dominos.insert(*it); domino_queue.push_back(*it); } } visited_pips[domino->side1] = 1; } if (!visited_pips[domino->side2]) { for (auto it = dominos_by_side[domino->side2].begin(); it != dominos_by_side[domino->side2].end(); it++) { if (ignored_dominos.count(*it) == 1) { continue; } if (visited_dominos.count(*it) == 0) { visited_dominos.insert(*it); domino_queue.push_back(*it); } } visited_pips[domino->side2] = 1; } } if (visited_dominos.size() != used_dominos.size()) { cout << "DFS invalid " << visited_dominos.size() << "/" << used_dominos.size() << " visited" << endl; // ignore_candidates.insert(used_dominos.begin(), used_dominos.end()); if (visited_dominos.size() > (used_dominos.size() / 2)) { for (auto it = used_dominos.begin(); it != used_dominos.end(); it++) { if (visited_dominos.count(*it) == 0) { ignore_candidates.insert(*it); } } } else { ignore_candidates.insert(used_dominos.begin(), used_dominos.end()); } return false; } // cout << "DFS VALID" << endl; return true; } bool evaluate() { unordered_set empty_set; return evaluate(empty_set); } void solve() { // cout << ignored_dominos.size() << " ignored dominos deep" << endl; unordered_set ignore_candidates; // populated in evaluate() if (evaluate(ignore_candidates)) { cout << "Found new max length " << max_length << endl; max_length = max(max_length, (int)(n - ignored_dominos.size())); return; } // Evaluate if it's worth going deeper based on previous findings if (max_length > (n - ignored_dominos.size() - 1)) { return; } // for (int i = 0; i < dominos_to_ignore.size(); i++) { for (auto it = ignore_candidates.begin(); it != ignore_candidates.end(); it++) { #define target_domino (*it) if (ignored_dominos.count(target_domino)) { continue; } ignored_dominos.insert(target_domino); solve(); ignored_dominos.erase(target_domino); } } // pips = vertices; dominos = edges // Solve Euler path int main(int argc, char *argv[]) { string inName = "test.in"; string outName = "test.out"; if (argc > 1) { inName = argv[1]; cout << "Using \"" << inName << "\" for test name" << endl; } else { cout << "Warning: no in name provided, defaulting to test.in" << endl; } if (argc > 2) { outName = argv[2]; cout << "Using \"" << outName << "\" for out name" << endl; } else { cout << "Warning: no out name proviced, defaulting to test.out" << endl; } ifstream in(inName); ofstream out(outName); in >> n; // cout << "n: " << n << endl; if (n < 2) { out << "1"; in.close(); out.close(); return 0; } for (int i = 0; i < n; i++) { Domino* domino = new Domino(); in >> (*domino).side1; in >> (*domino).side2; dominos[i] = domino; dominos_by_side[(domino -> side1)].push_back(domino); dominos_by_side[(domino -> side2)].push_back(domino); } ignored_dominos.clear(); solve(); // ignored_dominos.insert(dominos[0]); // cout << dominos[0]->side1 << " " << dominos[0]->side2 << endl; cout << "Result: " << max_length << endl; out << max_length << endl; return 0; }