/* * graph_examples.cpp * * Created on: 13.01.2015 г. * Author: trifon */ #include "graph.cpp" typedef Graph IntGraph; typedef LinkedListIterator VI; Graph sampleGraph() { Graph g; for(int i = 1; i <= 6; i++) g.addVertex(i); g.addEdge(1, 2); g.addEdge(2, 3); g.addEdge(2, 6); g.addEdge(1, 3); g.addEdge(3, 4); g.addEdge(3, 6); g.addEdge(4, 1); g.addEdge(4, 5); g.addEdge(6, 5); g.addEdge(5, 3); return g; } Graph fullGraph(int n) { Graph g; for(int i = 1; i <= n; i++) { g.addVertex(i); for(int j = 1; j <= n - 1; j++) g.addEdge(i, j); } return g; } void printGraph(Graph const& g) { for(int i = 1; i <= 6; i++) { cout << i << " -> "; for (VI it = g.successors(i); it; ++it) cout << *it << ' '; cout << endl; } } template void printDFSRec(Graph const& g, V const& v, LinkedList& visited) { cout << v << ' '; visited.insertEnd(v); for(LinkedListIterator it = g.successors(v); it; ++it) if (!member(visited.begin(), *it)) printDFSRec(g, *it, visited); } template void printDFS(Graph const& g, V const& v) { LinkedList l; printDFSRec(g, v, l); cout << endl; } template void printBFS(Graph const& g, V const& v) { LinkedList toVisit; toVisit.insertEnd(v); LinkedListIterator it = toVisit.begin(); while (it) { cout << *it << ' '; for(LinkedListIterator sit = g.successors(*it); sit; ++sit) if (!member(toVisit.begin(), *sit)) toVisit.insertEnd(*sit); ++it; } cout << endl; } // O(n*m) template bool findPathRec(Graph const& g, V const& a, V const& b, LinkedList& visited, LinkedList& path) { visited.insertEnd(a); path.insertEnd(a); if (a == b) return true; for(LinkedListIterator sit = g.successors(a); sit; ++sit) if (!member(visited.begin(), *sit) && findPathRec(g, *sit, b, visited, path)) return true; V tmp; path.deleteEnd(tmp); return false; } template LinkedList findPath(Graph const& g, V const& a, V const& b) { LinkedList visited, path; findPathRec(g, a, b, visited, path); return path; } // O(n!*n) template bool findPathRec2(Graph const& g, V const& a, V const& b, LinkedList& path) { path.insertEnd(a); if (a == b) return true; for(LinkedListIterator sit = g.successors(a); sit; ++sit) if (!member(path.begin(), *sit) && findPathRec2(g, *sit, b, path)) return true; V tmp; path.deleteEnd(tmp); return false; } template LinkedList findPath2(Graph const& g, V const& a, V const& b) { LinkedList path; findPathRec2(g, a, b, path); return path; } // O(n!*n) template void findAllPathsRec(Graph const& g, V const& a, V const& b, LinkedList& path) { path.insertEnd(a); if (a == b) cout << path; else for(LinkedListIterator sit = g.successors(a); sit; ++sit) if (!member(path.begin(), *sit)) findAllPathsRec(g, *sit, b, path); V tmp; path.deleteEnd(tmp); } template void findAllPaths(Graph const& g, V const& a, V const& b) { LinkedList path; findAllPathsRec(g, a, b, path); } template bool hasCycleFrom(Graph const& g, LinkedList& visited, V const& a) { if(member(visited, a)) return true; visited.insertEnd(a); for(LinkedListIterator it = g.successors(a); it; ++it) if (hasCycleFrom(g, visited, *it)) return true; return false; } template bool hasCycle(Graph const& g) { LinkedList visited, vertices = g.vertices(); for(LinkedListIterator it = vertices.begin(); it; ++it) if (!member(visited, *it) && hasCycleFrom(g, visited, *it)) return true; return false; } template struct Edge { V from, to; Edge(V const& _from = V(), V const& _to = V()) : from(_from), to(_to) {} bool operator==(Edge const& e) const { return e.from == from && e.to == to; } bool operator!=(Edge const& e) const { return e.from != from || e.to != to; } }; template ostream& operator<<(ostream& os, Edge const& e) { return os << '(' << e.from << ',' << e.to << ')'; } template bool findPathBFS(Graph const& g, V const& a, V const& b) { LinkedList > toVisit; toVisit.insertEnd(Edge(a,a)); LinkedListIterator > it = toVisit.begin(); while (it && (*it).to != b) { for(LinkedListIterator sit = g.successors((*it).to); sit; ++sit) { Edge e((*it).to, *sit); if (!member(toVisit.begin(), e)) toVisit.insertEnd(e); } ++it; } // !it <-> обходили сме всички върхове // (*it).to == b <-> намерили сме път if (it) { // извеждаме пътя LinkedList path; path.insertEnd(b); // насочваме итератора към (x,u) и повтаряме // докога? когато x == a приключваме! while ((*it).from != a) { // Нека *it == (u,v) V u = (*it).from; // добавяме u във пътя path path.insertBegin(u); // търсим първото ребро от вида (x,u) в toVisit it = toVisit.begin(); while (it && (*it).to != u) ++it; // сега *it == (x,u) } path.insertBegin(a); cout << path << endl; return true; } return false; } int main() { IntGraph g = sampleGraph(); printGraph(g); printDFS(g, 1); printBFS(g, 1); cout << "findPath: "; cout << findPath(g, 1, 5) << endl; cout << "findPathBFS: "; cout << findPathBFS(g, 1, 5) << endl; cout << "findPath2: "; cout << findPath2(g, 1, 5) << endl; findAllPaths(g, 1, 6); cout << "Has cycle? " << hasCycle(g) << endl; g = fullGraph(200); cout << "findPath:\n"; cout << findPath(g, 1, 200); // !!! cout << "findPath2:\n"; // !!! cout << findPath2(g, 1, 200); return 0; }