Grafalgo
Library of useful data structures and algorithms
|
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 }