#include #include #include #include #include #include using namespace std; typedef list Adjlist; class Node { public: string name; Adjlist edges; Node *backedge; // For determining a path in augmenting paths. int visited; }; class Edge { public: string name; Node *n1; // From node Node *n2; // To node Edge *reverse; // This lets you find your reverse edge quickly double capacity; double flow; Adjlist::iterator adj_ptr; // This lets you delete yourself // from the adjacently list quickly }; class Graph { public: // Methods: Graph(); void Print(); Node *Get_Node_By_Name(string name); // Data: map node_names; // All nodes by name. map edge_names; // All edges by name. Node *source; Node *sink; }; Node *Graph::Get_Node_By_Name(string name) // Creates the node if it does not yet exist { Node *n; map ::iterator nptr; nptr = node_names.find(name); if (nptr == node_names.end()) { n = new Node; n->name = name; n->backedge = NULL; n->visited = 0; node_names.insert(make_pair(name, n)); return n; } else { return nptr->second; } } Graph::Graph() // Create a graph from standard input. { string s, name1, name2; Node *n1; Node *n2; Edge *e; double cap; map ::iterator eptr; source = NULL; sink = NULL; while (!cin.fail()) { cin >> s; if (!cin.fail()) { if (s == "SOURCE") { if (source != NULL) { cerr << "Bad Graph -- multiple sources\n"; exit(1); } cin >> s; if (cin.fail()) { cerr << "Bad Graph - no source node given\n"; exit(1); } source = Get_Node_By_Name(s); } else if (s == "SINK") { if (sink != NULL) { cerr << "Bad Graph -- multiple sources\n"; exit(1); } cin >> s; if (cin.fail()) { cerr << "Bad Graph - no source node given\n"; exit(1); } sink = Get_Node_By_Name(s); } else if (s == "EDGE") { cin >> name1 >> name2 >> cap; if (cin.fail()) { cerr << "Bad Graph -- bad edge specification\n"; exit(1); } if (cap <= 0) { cerr << "Bad Graph -- bad edge capacity\n"; exit(1); } n1 = Get_Node_By_Name(name1); n2 = Get_Node_By_Name(name2); s = name1 + " -> " + name2; if (edge_names.find(s) != edge_names.end()) { cerr << "Bad Graph -- duplicate edge " << s << endl; exit(1); } e = new Edge; e->name = s; e->capacity = cap; e->flow = 0; e->n1 = n1; e->n2 = n2; n1->edges.push_front(e); e->adj_ptr = n1->edges.begin(); s = name2 + " -> " + name1; eptr = edge_names.find(s); if (eptr == edge_names.end()) { e->reverse = NULL; } else { e->reverse = eptr->second; e->reverse->reverse = e; } edge_names.insert(make_pair(e->name, e)); } } } if (source == NULL || sink == NULL) { cerr << "Bad Graph -- no source or no sink\n"; exit(1); } } void Graph::Print() { Adjlist::iterator alit; map ::iterator nit; map ::iterator elit; Edge *e; Node *n; cout << "Source: " << source->name << ", Sink: " << sink->name << endl; for (nit = node_names.begin(); nit != node_names.end(); nit++) { n = nit->second; cout << "Node " << n->name << ", Edges:"; for (alit = n->edges.begin(); alit != n->edges.end(); alit++) { e = *alit; cout << " (" << e->n2->name << "," << e->capacity << ")"; } cout << endl; } for (elit = edge_names.begin(); elit != edge_names.end(); elit++) { e = elit->second; cout << "Edge " << e->name << " -- "; if (e->reverse == NULL) { cout << "No reverse edge.\n"; } else { cout << "Reverse edge: " << e->reverse->name << endl; } } } main() { Graph *g; g = new Graph(); g->Print(); }