#include #include #include #include #include #include using namespace std; class Node { public: string name; vector adj; int visited; }; class Edge { public: string name; Node *n1; Node *n2; Edge *reverse; double original; double residual; double flow; }; class Graph { public: Graph(); ~Graph(); void Print(); Node *Get_Node(string &s); Edge *Get_Edge(Node *n1, Node *n2); double Find_Max_Flow(); double Find_Augmenting_Path(); int DFS(Node *n); Node *Source; Node *Sink; vector Nodes; vector Edges; map N_Map; map E_Map; }; double Graph::Find_Max_Flow() { double total; double f; Edge *e; int i; for (i = 0; i < Edges.size(); i++) { e = Edges[i]; e->flow = 0; e->residual = e->original; } total = 0; while (1) { f = Find_Augmenting_Path(); if (f == 0) { return total; } else { total += f; } } } double Graph::Find_Augmenting_Path() { int i; for (i = 0; i < Nodes.size(); i++) Nodes[i]->visited = 0; if (DFS(Source)) { printf("Quitting.\n"); } exit(0); } int Graph::DFS(Node *n) { int i; Edge *e; double f; if (n->visited) return 0; n->visited = 1; if (n == Sink) return 1; for (i = 0; i < n->adj.size(); i++) { e = n->adj[i]; if (e->residual > 0) { if (DFS(e->n2)) { printf("Found a path to the sink. Edge %s.\n", e->name.c_str()); return 1; } } } return 0; } void Graph::Print() { Node *n; Edge *e; int i, j; printf("Source: %s\n", Source->name.c_str()); printf("Sink: %s\n", Sink->name.c_str()); for (i = 0; i < Nodes.size(); i++) { n = Nodes[i]; printf("Node %s:", n->name.c_str()); for (j = 0; j < n->adj.size(); j++) { e = n->adj[j]; printf(" (%s:%.3lf)", e->name.c_str(), e->original); } printf("\n"); } } Graph::Graph() { string s, f, t; double cap; Node *n1, *n2; Edge *e; Source = NULL; Sink = NULL; while (cin >> s) { if (s == "SOURCE") { cin >> s; if (Source != NULL) { fprintf(stderr, "Can't specify two sources\n"); exit(1); } Source = Get_Node(s); } else if (s == "SINK") { cin >> s; if (Sink != NULL) { fprintf(stderr, "Can't specify two sinks\n"); exit(1); } Sink = Get_Node(s); } else if (s == "EDGE") { cin >> f >> t >> cap; n1 = Get_Node(f); n2 = Get_Node(t); e = Get_Edge(n1, n2); e->original += cap; if (e->reverse == NULL) { e->reverse = Get_Edge(n2, n1); e->reverse->reverse = e; n1->adj.push_back(e); n2->adj.push_back(e->reverse); } } } if (Source == NULL) { fprintf(stderr, "No Source.\n"); exit(1); } if (Sink == NULL) { fprintf(stderr, "No Sink.\n"); exit(1); } } Graph::~Graph() { int i; for (i = 0; i < Nodes.size(); i++) delete(Nodes[i]); for (i = 0; i < Edges.size(); i++) delete(Edges[i]); } Node *Graph::Get_Node(string &s) { map ::iterator nit; Node *n; nit = N_Map.find(s); if (nit != N_Map.end()) return nit->second; n = new Node; n->name = s; Nodes.push_back(n); N_Map.insert(make_pair(s, n)); return n; } Edge *Graph::Get_Edge(Node *n1, Node *n2) { map ::iterator eit; Edge *e; string name; name = n1->name + "->"; name += n2->name; eit = E_Map.find(name); if (eit != E_Map.end()) return eit->second; e = new Edge; e->name = name; e->n1 = n1; e->n2 = n2; e->original = 0; e->residual = 0; e->flow = 0; e->reverse = NULL; Edges.push_back(e); E_Map.insert(make_pair(name, e)); return e; } main() { Graph *g; double f; g = new Graph(); f = g->Find_Max_Flow(); printf("Max flow is %.3lf\n", f); }