#include #include #include #include using namespace std; class Graph { typedef bool *PBOOL; bool *buffer; PBOOL *adj; int order; virtual void create(int order = 0) { this->order = order; if (order == 0) { buffer = 0; adj = 0; return; } buffer = new bool[order*(order + 1)/2]; adj = new PBOOL[order]; for (int i = 0; i < order; ++i) { adj[i] = buffer + i*(2*order - i + 1)/2; } } virtual void clear() { delete [] buffer; delete [] adj; buffer = 0; adj = 0; order = 0; } virtual void copy(const Graph &object) { int order2 = object.order*(object.order + 1)/2; Graph::create(object.order); for (int i = 0; i < order2; ++i) { buffer[i] = object.buffer[i]; } } public: Graph() { create(); } Graph(const Graph &object) { Graph::copy(object); } ~Graph() { Graph::clear(); } Graph& operator=(const Graph &object) { if (this == &object) { return *this; } clear(); copy(object); return *this; } bool operator==(const Graph &object) const { if (order != object.order) { return false; } if (order == 0) { return true; } int order2 = order*(order + 1)/2; for (int i = 0; i < order2; ++i) { if (buffer[i] != object.buffer[i]) { return false; } } return true; } bool operator!=(const Graph &object) const { return !operator==(object); } bool operator()(int i, int j) const { int order2 = order*(order + 1)/2; if (i > j) { return adj[j][i - j]; } return adj[i][j - i]; } bool& operator()(int i, int j) { int order2 = order*(order + 1)/2; if (i > j) { return adj[j][i - j]; } return adj[i][j - i]; } void get(istream &istr = cin) { istr >> order; Graph::create(order); int order2 = order*(order + 1)/2; for (int i = 0; i < order2; ++i) { istr >> buffer[i]; } } void put(ostream &ostr = cout) const { ostr << order << "\n"; for (int i = 0; i < order; ++i) { for (int j = i; j < order; ++j) { ostr << " " << operator()(i, j); } ostr << "\n"; } } int nodeDegree(int n) const { int counter = 0; for (int i = 0; i < order; ++i) { if (operator()(n, i)) { ++counter; if (n == i) { ++counter; } } } return counter; } bool connected() const { if (order == 0) { return true; } Graph other(*this); for (int i = 0; i < order; ++i) { if (nodeDegree(i) > 0) { other(i, i) = true; } } bool stop = false; while(stop == false) { stop = true; for (int i = 0; i < order; ++i) { for (int j = i + 1; j < order; ++j) { if (other(i, j) == false) { for (int k = 0; k < order; ++k) { if (other(i, k) && other(k, j)) { stop = false; other(i, j) = true; break; } } } } } } bool *excludedNode = (bool*) alloca(order*sizeof(bool)); for (int i = 0; i < order; ++i) { excludedNode[i] = true; for (int j = 0; j <= i; ++j) { if (other(i, j)) { excludedNode[i] = false; break; } } if (excludedNode[i]) { continue; } for (int j = 0; j <= i; ++j) { if (excludedNode[j] == false && other(i, j) == false) { return false; } } } return true; } bool empty() const { int order2 = order*(order + 1)/2; for (int i = 0; i < order2; ++i) { if (buffer[i]) { return false; } } return true; } int nodes() const { return order; } bool eulerPath(list &path) const { if (connected() == false) { return false; } if (empty()) { path.clear(); return true; } int oddNodes = 0; int startNode = 0; for (int i = 0; i < order; ++i) { if (nodeDegree(i)%2 == 1) { ++oddNodes; startNode = i; if (oddNodes > 2) { return false; } } } if (oddNodes == 1) { return false; } path.clear(); path.push_back(startNode); int ¤tNode = startNode; Graph other(*this); int i; do { for (i = 0; i < order; ++i) { if (other(i, currentNode)) { bool loop = other(i, i); other(i, currentNode) = false; if (currentNode != i) { other(i, i) = true; } bool isConnected = other.connected(); other(i, i) = loop; if (isConnected) { other(i, i) = false; other(i, currentNode) = false; currentNode = i; path.push_back(currentNode); break; } else { other(i, currentNode) = true; } } } } while(i < order); return true; } }; istream& operator>>(istream &istr, Graph &object) { object.get(istr); return istr; } ostream& operator<<(ostream &ostr, const Graph &object) { object.put(ostr); return ostr; } int main() { Graph g; list path; cout << "Unesi graf" << endl; cin >> g; if (g.eulerPath(path)) { cout << "Ojlerov put glasi " << endl; for (list::const_iterator i = path.begin(); i != path.end(); ++i) { cout << *i << endl; } } else { cout << "Graf nije Ojlerov" << endl; } return EXIT_SUCCESS; }