#include #include "Fields.h" #include #include #include #include #include using namespace std; class Vertex; class Edge { public: Edge(Vertex *vtx1, Vertex *vtx2) { v1 = vtx1; v2 = vtx2; } Vertex *getVertex1() { return v1; } Vertex *getVertex2() { return v2; } protected: Vertex *v1; Vertex *v2; }; class Vertex { protected: string name; list edges; int nincident; list::iterator edgesIter; bool visited; public: Vertex(string n) { name = n; nincident = 0; visited = false; } string getName() { return name; } bool getVisited() { return visited; } void setVisited(bool flag) { visited = flag; } int getNumIncident() { return nincident; } void firstEdge() { edgesIter = edges.begin(); } void nextEdge() { edgesIter++; } bool endOfEdges() { return edgesIter == edges.end(); } Edge *getEdge() { return *edgesIter; } void addEdge(Edge *e) { edges.push_back(e); e->getVertex2()->nincident++; } void deleteEdge() { Edge *e = getEdge(); e->getVertex2()->nincident--; edgesIter = edges.erase(edgesIter); } }; void find_zero_incident(map &g, queue &start_vertices) { Vertex *v; map::iterator verticesIter; for (verticesIter = g.begin(); verticesIter != g.end(); verticesIter++) { v = verticesIter->second; if (v->getNumIncident() == 0) { start_vertices.push(v); } } } void dfs(Vertex *v, stack &top_order) { v->setVisited(true); for (v->firstEdge(); !v->endOfEdges(); v->nextEdge()) { Edge *e = v->getEdge(); Vertex *toVertex = e->getVertex2(); if (!toVertex->getVisited()) dfs(toVertex, top_order); } top_order.push(v); } main() { Fields *f; map g; stack topological_order; queue start_vertices; Vertex *v; Vertex *v2; Edge *e; string s; v = 0; f = new Fields(); while (f->get_line() >= 0) { if (f->get_NF() > 0) { if (f->get_field(0) == "CLASS") { if (f->get_NF() != 2) { fprintf(stderr, "%d: CLASS name\n", f->get_line_number()); exit(1); } s = f->get_field(1); v = g[s]; if (v == 0) { v = new Vertex(s); g[s] = v; } } else if (f->get_field(0) == "PREREQ") { if (f->get_NF() != 2) { fprintf(stderr, "%d: PREREQ class\n", f->get_line_number()); exit(1); } if (v == 0) { fprintf(stderr, "%d: PREREQ -- no current vertex\n", f->get_line_number()); exit(1); } s = f->get_field(1); v2 = g[s]; if (v2 == 0) { v2 = new Vertex(s); g[s] = v2; } e = new Edge(v2, v); v2->addEdge(e); } else { fprintf(stderr, "%d: lines must be CLASS or PREREQ\n", f->get_line_number()); exit(1); } } } find_zero_incident(g, start_vertices); while (!start_vertices.empty()) { v = start_vertices.front(); start_vertices.pop(); dfs(v, topological_order); } while (!topological_order.empty()) { v = topological_order.top(); topological_order.pop(); printf("%s\n", v->getName().c_str()); } }