Grafalgo
Library of useful data structures and algorithms
|
00001 // usage: 00002 // check [src] 00003 // 00004 // check reads two graphs from stdin, and checks to see 00005 // if the second is a shortest path tree of the first. 00006 // It prints a message for each discrepancy that it finds. 00007 // 00008 // This program is not bullet-proof. Caveat emptor. 00009 00010 #include "stdinc.h" 00011 #include "List.h" 00012 #include "Wdigraph.h" 00013 00014 using namespace grafalgo; 00015 00016 void check(int, Wdigraph&, Wdigraph&); 00017 00018 int main(int argc, char *argv[]) { 00019 int s = 1; 00020 if (argc == 2 && sscanf(argv[1],"%d",&s) != 1) 00021 Util::fatal("usage: check [src]"); 00022 Wdigraph dig; cin >> dig; 00023 Wdigraph sptree; cin >> sptree; 00024 check(s,dig,sptree); 00025 } 00026 00027 void check(int s, Wdigraph& dig, Wdigraph& sptree) { 00028 // Verify that sptree is a shortest path tree of dig. 00029 vertex u,v; edge e, f; 00030 00031 // check size of sptree matches dig 00032 if (sptree.n() != dig.n() || sptree.m() != sptree.n()-1) 00033 Util::fatal("spt_check: size error, aborting"); 00034 00035 // check that sptree is a subgraph of dig 00036 for (v = 1; v <= sptree.n(); v++) { 00037 if (v == s) continue; 00038 f = sptree.firstIn(v); 00039 if (f == 0) 00040 cout << "check: non-root vertex " << v 00041 << " has no incoming edge\n"; 00042 u = sptree.tail(f); 00043 for (e = dig.firstIn(v); ; e = dig.nextOut(v,e)) { 00044 if (e == 0) { 00045 cout << "check: edge (" << u << "," << v 00046 << ") in sptree is not in dig\n"; 00047 } 00048 if (dig.tail(e) == u) break; 00049 } 00050 } 00051 00052 // check that sptree reaches all the vertices 00053 bool* mark = new bool[sptree.n()+1]; int marked; 00054 for (u = 1; u <= sptree.n(); u++) mark[u] = false; 00055 mark[s] = true; marked = 1; 00056 List q(dig.n()); q.addLast(s); 00057 while (!q.empty()) { 00058 u = q.first(); q.removeFirst(); 00059 for (e = sptree.firstOut(u); e != 0; e = sptree.nextOut(u,e)) { 00060 v = sptree.head(e); 00061 if (!mark[v]) { 00062 q.addLast(v); mark[v] = true; marked++; 00063 } 00064 } 00065 } 00066 if (marked != sptree.n()) { 00067 cout << "check: sptree does not reach all vertices\n"; 00068 return; 00069 } 00070 00071 // check that tree is minimum 00072 int du, dv; string s1; 00073 for (u = 1; u <= dig.n(); u++) { 00074 du = sptree.firstIn(u) == 0 ? 00075 0 : sptree.length(sptree.firstIn(u)); 00076 for (e = dig.firstOut(u); e != 0; e = dig.nextOut(u,e)) { 00077 v = dig.head(e); 00078 dv = sptree.firstIn(v) == 0 ? 00079 0 : sptree.length(sptree.firstIn(v)); 00080 if (dv > du + dig.length(e)) 00081 cout << "check: " << dig.edge2string(e,s1) 00082 << ") violates spt condition\n"; 00083 if (sptree.firstIn(v) != 0 && 00084 sptree.tail(sptree.firstIn(v)) == u && 00085 dv != du + dig.length(e)) 00086 cout << "check: tree edge " 00087 << dig.edge2string(e,s1) 00088 << " violates spt condition\n"; 00089 } 00090 } 00091 }