Grafalgo
Library of useful data structures and algorithms
/Users/jst/src/grafalgo/cpp/graphAlgorithms/mcFlo/check.cpp
00001 // usage: check
00002 //
00003 // Check reads a Wflograph from stdin, with a flow and checks
00004 // that its a legal maximum flow and has a minimum cost.
00005 //
00006 
00007 #include "stdinc.h"
00008 #include "Wflograph.h"
00009 #include "List.h"
00010 
00011 using namespace grafalgo;
00012 
00013 int main() {
00014         vertex u,v,w; edge e; int s;
00015         Wflograph wfg; cin >> wfg;
00016 
00017         // Check that capacity constraints are respected.
00018         for (e = 1; e <= wfg.m(); e++) {
00019                 u = wfg.tail(e); v = wfg.head(e);
00020                 if (wfg.f(u,e) < 0)
00021                         printf("Negative flow on edge %d=(%d,%d)\n",e,u,v);
00022                 if (wfg.f(u,e) > wfg.cap(u,e))
00023                         printf("Flow exceeds capacity on edge %d=(%d,%d)\n",
00024                                 e,u,v);
00025         }
00026 
00027         // Make sure each vertex is balanced.
00028         for (u = 2; u < wfg.n(); u++) { 
00029                 s = 0;
00030                 for (e = wfg.firstAt(u); e != 0; e = wfg.nextAt(u,e)) {
00031                         if (u == wfg.head(e))
00032                                 s += wfg.f(wfg.tail(e),e);
00033                         else
00034                                 s -= wfg.f(u,e);
00035                 }
00036                 if (s != 0)
00037                         printf("Vertex %d is not balanced\n",u);
00038         }
00039 
00040         // Check that there is no augmenting path.
00041         int *d = new int[wfg.n()+1];
00042         for (u = 1; u <= wfg.n(); u++) d[u] = wfg.n();
00043         d[1] = 0;
00044         List q(wfg.n()); q.addLast(1);
00045         while (!q.empty()) {
00046                 u = q.first(); q.removeFirst();
00047                 for (e = wfg.firstAt(u); e != 0; e = wfg.nextAt(u,e)) {
00048                         v = wfg.mate(u,e);
00049                         if (wfg.res(u,e) > 0 && d[v] > d[u] + 1) {
00050                                 d[v] = d[u] + 1;
00051                                 q.addLast(v);
00052                         }
00053                 }
00054         }
00055         if (d[wfg.n()] < wfg.n()) printf("Not a maximum flow\n");
00056 
00057         // Check that there are no negative cost cycles in residual graph.
00058         int** cst = new int*[wfg.n()+1];
00059         for (u = 1; u <= wfg.n(); u++) {
00060                 cst[u] = new int[wfg.n()+1];
00061         }
00062         for (u = 1; u <= wfg.n(); u++) {
00063                 for (v = 1; v <= wfg.n(); v++) {
00064                         if (u == v) cst[u][v] = 0;
00065                         else cst[u][v] = Util::BIGINT32;
00066                 }
00067         }
00068         for (u = 1; u <= wfg.n(); u++) {
00069                 for (e = wfg.firstAt(u); e != 0; e = wfg.nextAt(u,e)) {
00070                         v = wfg.mate(u,e);
00071                         if (wfg.res(u,e) > 0)
00072                                 cst[u][v] = min(cst[u][v],wfg.cost(u,e));
00073                 }
00074         }
00075         for (v = 1; v <= wfg.n(); v++) {
00076                 if (cst[v][v] < 0) {
00077                         printf("Vertex %2d on a negative cost cycle\n",v);
00078                         exit(0);
00079                 }
00080                 for (u = 1; u <= wfg.n(); u++) {
00081                         for (w = 1; w <= wfg.n(); w++) {
00082                                 if (cst[u][v] != Util::BIGINT32 &&
00083                                     cst[v][w] != Util::BIGINT32 &&
00084                                     cst[u][w] > cst[u][v] + cst[v][w]) {
00085                                         cst[u][w] = cst[u][v] + cst[v][w];
00086                                 }
00087                         }
00088                 }
00089         }
00090 }
 All Classes Files Functions Variables Typedefs Friends