程序如下:
1 #ifndef GRAPH_H 2 #define GRAPH_H 3 4 #include "Object.h" 5 #include "SharedPointer.h" 6 #include "Array.h" 7 #include "DynamicArray.h" 8 #include "LinkQueue.h" 9 #include "LinkStack.h" 10 #include "Sort.h" 11 12 namespace DTLib 13 { 14 15 template < typename E > 16 struct Edge : public Object 17 { 18 int b; 19 int e; 20 E data; 21 22 Edge(int i=-1, int j=-1) 23 { 24 b = i; 25 e = j; 26 } 27 28 Edge(int i, int j, const E& value) 29 { 30 b = i; 31 e = j; 32 data = value; 33 } 34 35 bool operator == (const Edge<E>& obj) 36 { 37 return (b == obj.b) && (e == obj.e); //在这里不关注权值大小 38 } 39 40 bool operator != (const Edge<E>& obj) 41 { 42 return !(*this == obj); 43 } 44 45 bool operator < (const Edge<E>& obj) 46 { 47 return (data < obj.data); 48 } 49 50 bool operator > (const Edge<E>& obj) 51 { 52 return (data > obj.data); 53 } 54 }; 55 56 template < typename V, typename E > 57 class Graph : public Object 58 { 59 protected: 60 template < typename T > 61 DynamicArray<T>* toArray(LinkQueue<T>& queue) 62 { 63 DynamicArray<T>* ret = new DynamicArray<T>(queue.length()); 64 65 if( ret != NULL ) 66 { 67 for(int i=0; i<ret->length(); i++, queue.remove()) 68 { 69 ret->set(i, queue.front()); 70 } 71 } 72 else 73 { 74 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create ret object..."); 75 } 76 77 return ret; 78 } 79 80 SharedPointer< Array<Edge<E> > > getUndirectedEdges() 81 { 82 DynamicArray<Edge<E>>* ret = NULL; 83 84 if( asUndirected() ) 85 { 86 LinkQueue<Edge<E>> queue; 87 88 for(int i=0; i<vCount(); i++) 89 { 90 for(int j=i; j<vCount(); j++) 91 { 92 if( isAdjacent(i, j) ) 93 { 94 queue.add(Edge<E>(i, j, getEdge(i, j))); 95 } 96 } 97 } 98 99 ret = toArray(queue); 100 } 101 else 102 { 103 THROW_EXCEPTION(InvalidOperationException, "This function is for undirected graph only..."); 104 } 105 106 return ret; 107 } 108 109 int find(Array<int>& p, int v) 110 { 111 while( p[v] != -1) 112 { 113 v = p[v]; 114 } 115 116 return v; 117 } 118 public: 119 virtual V getVertex(int i) = 0; 120 virtual bool getVertex(int i, V& value) = 0; 121 virtual bool setVertex(int i, const V& value) = 0; 122 virtual SharedPointer< Array<int> > getAdjacent(int i) = 0; 123 virtual bool isAdjacent(int i, int j) = 0; 124 virtual E getEdge(int i, int j) = 0; 125 virtual bool getEdge(int i, int j, E& value) = 0; 126 virtual bool setEdge(int i, int j, const E& value) = 0; 127 virtual bool removeEdge(int i, int j) = 0; 128 virtual int vCount() = 0; 129 virtual int eCount() = 0; 130 virtual int OD(int i) = 0; 131 virtual int ID(int i) = 0; 132 133 virtual int TD(int i) 134 { 135 return ID(i) + OD(i); 136 } 137 138 bool asUndirected() 139 { 140 bool ret = true; 141 142 for(int i=0; i<vCount(); i++) 143 { 144 for(int j=0; j<vCount(); j++) 145 { 146 if( isAdjacent(i, j) ) 147 { 148 ret = ret && isAdjacent(j, i) && (getEdge(i, j) == getEdge(j, i)); 149 } 150 } 151 } 152 153 return ret; 154 } 155 156 SharedPointer< Array< Edge<E > > > prim(const E& LIMIT, const bool MINIUM = true) //参数为理论上的最大权值 157 { 158 LinkQueue< Edge<E> > ret; 159 160 if( asUndirected() ) 161 { 162 DynamicArray<int> adjVex(vCount()); 163 DynamicArray<bool> mark(vCount()); 164 DynamicArray<E> cost(vCount()); 165 SharedPointer< Array<int> > aj = NULL; 166 bool end = false; 167 int v = 0; 168 169 for(int i=0; i<vCount(); i++) 170 { 171 adjVex[i] = -1; 172 mark[i] = false; 173 cost[i] = LIMIT; 174 } 175 176 mark[v] = true; 177 178 aj = getAdjacent(v); 179 180 for(int j=0; j<aj->length(); j++) 181 { 182 cost[(*aj)[j]] = getEdge(v, (*aj)[j]); 183 adjVex[(*aj)[j]] = v; 184 } 185 186 for(int i=0; (i<vCount()) && !end; i++) 187 { 188 E m = LIMIT; 189 int k = -1; 190 191 for(int j=0; j<vCount(); j++) 192 { 193 if( !mark[j] && (MINIUM ? (cost[j] < m) : (cost[j] > m))) 194 { 195 m = cost[j]; 196 k = j; 197 } 198 } 199 200 end = (k == -1); 201 202 if( !end ) 203 { 204 ret.add(Edge<E>(adjVex[k], k, getEdge(adjVex[k], k))); 205 206 mark[k] = true; 207 208 aj = getAdjacent(k); 209 210 for(int j=0; j<aj->length(); j++) 211 { 212 if( !mark[(*aj)[j]] && (MINIUM ? (getEdge(k, (*aj)[j]) < cost[(*aj)[j]]) : (getEdge(k, (*aj)[j]) > cost[(*aj)[j]])) ) 213 { 214 cost[(*aj)[j]] = getEdge(k, (*aj)[j]); 215 adjVex[(*aj)[j]] = k; 216 } 217 } 218 } 219 } 220 } 221 else 222 { 223 THROW_EXCEPTION(InvalidOperationException, "Prim operator is for undirected graph only..."); 224 } 225 226 if( ret.length() != (vCount() - 1) ) 227 { 228 THROW_EXCEPTION(InvalidOperationException, "No enough edge for prim operation..."); 229 } 230 231 return toArray(ret); 232 } 233 234 SharedPointer< Array<Edge<E> > > kruskal(const bool MINMUM = true) 235 { 236 LinkQueue< Edge<E> > ret; 237 238 SharedPointer< Array< Edge<E> > > edges = getUndirectedEdges(); 239 240 DynamicArray<int> p(vCount()); //前驱标记数组 241 242 for(int i=0; i<p.length(); i++) 243 { 244 p[i] = -1; 245 } 246 247 Sort::Shell(*edges, MINMUM); 248 249 for(int i=0; (i<edges->length()) && (ret.length() < (vCount() - 1)); i++) 250 { 251 int b = find(p, (*edges)[i].b); 252 int e = find(p, (*edges)[i].e); 253 254 if( b != e ) 255 { 256 p[e] = b; 257 258 ret.add((*edges)[i]); 259 } 260 } 261 262 if( ret.length() != (vCount() - 1) ) 263 { 264 THROW_EXCEPTION(InvalidOperationException, "No enough edges for Kruskal operation..."); 265 } 266 267 return toArray(ret); 268 } 269 270 SharedPointer< Array<int> > BFS(int i) 271 { 272 DynamicArray<int>* ret = NULL; 273 274 if( (0 <= i) && (i < vCount()) ) 275 { 276 LinkQueue<int> q; 277 LinkQueue<int> r; 278 DynamicArray<bool> visited(vCount()); 279 280 for(int i=0; i<visited.length(); i++) 281 { 282 visited[i] = false; 283 } 284 285 q.add(i); 286 287 while( q.length() > 0 ) 288 { 289 int v = q.front(); 290 291 q.remove(); 292 293 if( !visited[v] ) 294 { 295 SharedPointer< Array<int> > aj = getAdjacent(v); 296 297 for(int j=0; j<aj->length(); j++) 298 { 299 q.add((*aj)[j]); 300 } 301 302 r.add(v); 303 304 visited[v] = true; 305 } 306 } 307 308 ret = toArray(r); 309 } 310 else 311 { 312 THROW_EXCEPTION(InvalidParameterException, "Index i is invalid..."); 313 } 314 315 return ret; 316 } 317 318 SharedPointer< Array<int> > DFS(int i) 319 { 320 DynamicArray<int>* ret = NULL; 321 322 if( (0 <= i) && (i < vCount()) ) 323 { 324 LinkStack<int> s; 325 LinkQueue<int> r; 326 DynamicArray<bool> visited(vCount()); 327 328 for(int j=0; j<visited.length(); j++) 329 { 330 visited[j] = false; 331 } 332 333 s.push(i); 334 335 while( s.size() > 0 ) 336 { 337 int v = s.top(); 338 339 s.pop(); 340 341 if( !visited[v] ) 342 { 343 SharedPointer< Array<int> > aj = getAdjacent(v); 344 345 for(int j=aj->length() - 1; j>=0; j--) 346 { 347 s.push((*aj)[j]); 348 } 349 350 r.add(v); 351 352 visited[v] = true; 353 } 354 } 355 356 ret = toArray(r); 357 } 358 else 359 { 360 THROW_EXCEPTION(InvalidParameterException, "Index i is invalid..."); 361 } 362 363 return ret; 364 } 365 366 SharedPointer<Array<int>> dijkstra(int i, int j, const E& LIMIT) 367 { 368 LinkQueue<int> ret; 369 370 if( (0 <= i) && (i < vCount()) && (0 <= j) && (j < vCount()) ) 371 { 372 DynamicArray<E> dist(vCount()); 373 DynamicArray<int> path(vCount()); 374 DynamicArray<bool> mark(vCount()); 375 376 for(int k=0; k<vCount(); k++) 377 { 378 mark[k] = false; 379 path[k] = -1; 380 381 dist[k] = isAdjacent(i, k) ? (path[k] = i, getEdge(i, k)) : LIMIT; 382 } 383 384 mark[i] = true; 385 386 for(int k=0; k<vCount(); k++) 387 { 388 E m = LIMIT; 389 int u = -1; 390 391 for(int w=0; w<vCount(); w++) 392 { 393 if( !mark[w] && (dist[w] < m) ) 394 { 395 m = dist[w]; 396 u = w; 397 } 398 } 399 400 if( u == -1 ) 401 { 402 break; 403 } 404 405 mark[u] = true; 406 407 for(int w=0; w<vCount(); w++) 408 { 409 if( !mark[w] && isAdjacent(u, w) && (dist[u] + getEdge(u, w) < dist[w]) ) 410 { 411 dist[w] = dist[u] + getEdge(u, w); 412 path[w] = u; 413 } 414 } 415 } 416 417 LinkStack<int> s; 418 419 s.push(j); 420 421 for(int k=path[j]; k != -1; k=path[k]) 422 { 423 s.push(k); 424 } 425 426 while( s.size() > 0 ) 427 { 428 ret.add(s.top()); 429 430 s.pop(); 431 } 432 } 433 else 434 { 435 THROW_EXCEPTION(InvalidParameterException, "Index<i, j> is invalid..."); 436 } 437 438 if( ret.length() < 2 ) 439 { 440 THROW_EXCEPTION(ArithmeticException, "There is no path grom i to j..."); 441 } 442 443 return toArray(ret); 444 } 445 446 int floyd(int x, int y, const E& LIMIT) 447 { 448 int ret = -1; 449 450 if( (0 <= x) && (x < vCount()) && (0 <= y) && ( y < vCount()) ) 451 { 452 DynamicArray< DynamicArray<E> > dist(vCount()); 453 454 for(int k=0; k<vCount(); k++) 455 { 456 dist[k].resize(vCount()); 457 } 458 459 for(int i = 0; i<vCount(); i++) 460 { 461 for(int j=0; j<vCount(); j++) 462 { 463 dist[i][j] = isAdjacent(i, j) ? getEdge(i, j) : LIMIT; 464 } 465 } 466 467 for(int k=0; k<vCount(); k++) 468 { 469 for(int i = 0; i<vCount(); i++) 470 { 471 for(int j=0; j<vCount(); j++) 472 { 473 if( (dist[i][k] + dist[k][j]) < dist[i][j] ) 474 { 475 dist[i][j] = dist[i][k] + dist[k][j]; 476 } 477 } 478 } 479 } 480 481 ret = dist[x][y]; 482 483 } 484 else 485 { 486 THROW_EXCEPTION(ArithmeticException, "Index<x, y> is invalid..."); 487 } 488 489 return ret; 490 } 491 }; 492 493 } 494 495 #endif // GRAPH_H
测试程序如下:
1 #include <iostream> 2 #include "MatrixGraph.h" 3 #include "ListGraph.h" 4 5 using namespace std; 6 using namespace DTLib; 7 8 template< typename V, typename E > 9 Graph<V, E>& GraphEasy() 10 { 11 static MatrixGraph<4, V, E> g; 12 13 g.setEdge(0, 1, 1); 14 g.setEdge(0, 2, 3); 15 g.setEdge(1, 2, 1); 16 g.setEdge(1, 3, 4); 17 g.setEdge(2, 3, 1); 18 19 return g; 20 } 21 22 template< typename V, typename E > 23 Graph<V, E>& GraphComplex() 24 { 25 static ListGraph<V, E> g(5); 26 27 g.setEdge(0, 1, 10); 28 g.setEdge(0, 3, 30); 29 g.setEdge(0, 4, 100); 30 31 g.setEdge(1, 2, 50); 32 33 g.setEdge(2, 4, 10); 34 35 g.setEdge(3, 2, 20); 36 g.setEdge(3, 4, 60); 37 38 return g; 39 } 40 41 template< typename V, typename E > 42 Graph<V, E>& GraphSample() 43 { 44 static ListGraph<V, E> g(3); 45 46 g.setEdge(0, 1, 4); 47 g.setEdge(0, 2, 11); 48 49 g.setEdge(1, 2, 2); 50 g.setEdge(1, 0, 6); 51 52 g.setEdge(2, 0, 3); 53 54 return g; 55 } 56 57 int main() 58 { 59 Graph<int, int>& g = GraphSample<int, int>(); 60 //int r = g.floyd(0, 2, 65536); 61 62 for(int i=0; i<g.vCount();i++) 63 { 64 for(int j=0; j<g.vCount(); j++) 65 { 66 cout << g.floyd(i, j, 65536) << " "; 67 } 68 69 cout << endl; 70 } 71 72 cout << endl; 73 return 0; 74 }
结果如下:
程序改进如下:
1 #ifndef GRAPH_H 2 #define GRAPH_H 3 4 #include "Object.h" 5 #include "SharedPointer.h" 6 #include "Array.h" 7 #include "DynamicArray.h" 8 #include "LinkQueue.h" 9 #include "LinkStack.h" 10 #include "Sort.h" 11 12 namespace DTLib 13 { 14 15 template < typename E > 16 struct Edge : public Object 17 { 18 int b; 19 int e; 20 E data; 21 22 Edge(int i=-1, int j=-1) 23 { 24 b = i; 25 e = j; 26 } 27 28 Edge(int i, int j, const E& value) 29 { 30 b = i; 31 e = j; 32 data = value; 33 } 34 35 bool operator == (const Edge<E>& obj) 36 { 37 return (b == obj.b) && (e == obj.e); //在这里不关注权值大小 38 } 39 40 bool operator != (const Edge<E>& obj) 41 { 42 return !(*this == obj); 43 } 44 45 bool operator < (const Edge<E>& obj) 46 { 47 return (data < obj.data); 48 } 49 50 bool operator > (const Edge<E>& obj) 51 { 52 return (data > obj.data); 53 } 54 }; 55 56 template < typename V, typename E > 57 class Graph : public Object 58 { 59 protected: 60 template < typename T > 61 DynamicArray<T>* toArray(LinkQueue<T>& queue) 62 { 63 DynamicArray<T>* ret = new DynamicArray<T>(queue.length()); 64 65 if( ret != NULL ) 66 { 67 for(int i=0; i<ret->length(); i++, queue.remove()) 68 { 69 ret->set(i, queue.front()); 70 } 71 } 72 else 73 { 74 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create ret object..."); 75 } 76 77 return ret; 78 } 79 80 SharedPointer< Array<Edge<E> > > getUndirectedEdges() 81 { 82 DynamicArray<Edge<E>>* ret = NULL; 83 84 if( asUndirected() ) 85 { 86 LinkQueue<Edge<E>> queue; 87 88 for(int i=0; i<vCount(); i++) 89 { 90 for(int j=i; j<vCount(); j++) 91 { 92 if( isAdjacent(i, j) ) 93 { 94 queue.add(Edge<E>(i, j, getEdge(i, j))); 95 } 96 } 97 } 98 99 ret = toArray(queue); 100 } 101 else 102 { 103 THROW_EXCEPTION(InvalidOperationException, "This function is for undirected graph only..."); 104 } 105 106 return ret; 107 } 108 109 int find(Array<int>& p, int v) 110 { 111 while( p[v] != -1) 112 { 113 v = p[v]; 114 } 115 116 return v; 117 } 118 public: 119 virtual V getVertex(int i) = 0; 120 virtual bool getVertex(int i, V& value) = 0; 121 virtual bool setVertex(int i, const V& value) = 0; 122 virtual SharedPointer< Array<int> > getAdjacent(int i) = 0; 123 virtual bool isAdjacent(int i, int j) = 0; 124 virtual E getEdge(int i, int j) = 0; 125 virtual bool getEdge(int i, int j, E& value) = 0; 126 virtual bool setEdge(int i, int j, const E& value) = 0; 127 virtual bool removeEdge(int i, int j) = 0; 128 virtual int vCount() = 0; 129 virtual int eCount() = 0; 130 virtual int OD(int i) = 0; 131 virtual int ID(int i) = 0; 132 133 virtual int TD(int i) 134 { 135 return ID(i) + OD(i); 136 } 137 138 bool asUndirected() 139 { 140 bool ret = true; 141 142 for(int i=0; i<vCount(); i++) 143 { 144 for(int j=0; j<vCount(); j++) 145 { 146 if( isAdjacent(i, j) ) 147 { 148 ret = ret && isAdjacent(j, i) && (getEdge(i, j) == getEdge(j, i)); 149 } 150 } 151 } 152 153 return ret; 154 } 155 156 SharedPointer< Array< Edge<E > > > prim(const E& LIMIT, const bool MINIUM = true) //参数为理论上的最大权值 157 { 158 LinkQueue< Edge<E> > ret; 159 160 if( asUndirected() ) 161 { 162 DynamicArray<int> adjVex(vCount()); 163 DynamicArray<bool> mark(vCount()); 164 DynamicArray<E> cost(vCount()); 165 SharedPointer< Array<int> > aj = NULL; 166 bool end = false; 167 int v = 0; 168 169 for(int i=0; i<vCount(); i++) 170 { 171 adjVex[i] = -1; 172 mark[i] = false; 173 cost[i] = LIMIT; 174 } 175 176 mark[v] = true; 177 178 aj = getAdjacent(v); 179 180 for(int j=0; j<aj->length(); j++) 181 { 182 cost[(*aj)[j]] = getEdge(v, (*aj)[j]); 183 adjVex[(*aj)[j]] = v; 184 } 185 186 for(int i=0; (i<vCount()) && !end; i++) 187 { 188 E m = LIMIT; 189 int k = -1; 190 191 for(int j=0; j<vCount(); j++) 192 { 193 if( !mark[j] && (MINIUM ? (cost[j] < m) : (cost[j] > m))) 194 { 195 m = cost[j]; 196 k = j; 197 } 198 } 199 200 end = (k == -1); 201 202 if( !end ) 203 { 204 ret.add(Edge<E>(adjVex[k], k, getEdge(adjVex[k], k))); 205 206 mark[k] = true; 207 208 aj = getAdjacent(k); 209 210 for(int j=0; j<aj->length(); j++) 211 { 212 if( !mark[(*aj)[j]] && (MINIUM ? (getEdge(k, (*aj)[j]) < cost[(*aj)[j]]) : (getEdge(k, (*aj)[j]) > cost[(*aj)[j]])) ) 213 { 214 cost[(*aj)[j]] = getEdge(k, (*aj)[j]); 215 adjVex[(*aj)[j]] = k; 216 } 217 } 218 } 219 } 220 } 221 else 222 { 223 THROW_EXCEPTION(InvalidOperationException, "Prim operator is for undirected graph only..."); 224 } 225 226 if( ret.length() != (vCount() - 1) ) 227 { 228 THROW_EXCEPTION(InvalidOperationException, "No enough edge for prim operation..."); 229 } 230 231 return toArray(ret); 232 } 233 234 SharedPointer< Array<Edge<E> > > kruskal(const bool MINMUM = true) 235 { 236 LinkQueue< Edge<E> > ret; 237 238 SharedPointer< Array< Edge<E> > > edges = getUndirectedEdges(); 239 240 DynamicArray<int> p(vCount()); //前驱标记数组 241 242 for(int i=0; i<p.length(); i++) 243 { 244 p[i] = -1; 245 } 246 247 Sort::Shell(*edges, MINMUM); 248 249 for(int i=0; (i<edges->length()) && (ret.length() < (vCount() - 1)); i++) 250 { 251 int b = find(p, (*edges)[i].b); 252 int e = find(p, (*edges)[i].e); 253 254 if( b != e ) 255 { 256 p[e] = b; 257 258 ret.add((*edges)[i]); 259 } 260 } 261 262 if( ret.length() != (vCount() - 1) ) 263 { 264 THROW_EXCEPTION(InvalidOperationException, "No enough edges for Kruskal operation..."); 265 } 266 267 return toArray(ret); 268 } 269 270 SharedPointer< Array<int> > BFS(int i) 271 { 272 DynamicArray<int>* ret = NULL; 273 274 if( (0 <= i) && (i < vCount()) ) 275 { 276 LinkQueue<int> q; 277 LinkQueue<int> r; 278 DynamicArray<bool> visited(vCount()); 279 280 for(int i=0; i<visited.length(); i++) 281 { 282 visited[i] = false; 283 } 284 285 q.add(i); 286 287 while( q.length() > 0 ) 288 { 289 int v = q.front(); 290 291 q.remove(); 292 293 if( !visited[v] ) 294 { 295 SharedPointer< Array<int> > aj = getAdjacent(v); 296 297 for(int j=0; j<aj->length(); j++) 298 { 299 q.add((*aj)[j]); 300 } 301 302 r.add(v); 303 304 visited[v] = true; 305 } 306 } 307 308 ret = toArray(r); 309 } 310 else 311 { 312 THROW_EXCEPTION(InvalidParameterException, "Index i is invalid..."); 313 } 314 315 return ret; 316 } 317 318 SharedPointer< Array<int> > DFS(int i) 319 { 320 DynamicArray<int>* ret = NULL; 321 322 if( (0 <= i) && (i < vCount()) ) 323 { 324 LinkStack<int> s; 325 LinkQueue<int> r; 326 DynamicArray<bool> visited(vCount()); 327 328 for(int j=0; j<visited.length(); j++) 329 { 330 visited[j] = false; 331 } 332 333 s.push(i); 334 335 while( s.size() > 0 ) 336 { 337 int v = s.top(); 338 339 s.pop(); 340 341 if( !visited[v] ) 342 { 343 SharedPointer< Array<int> > aj = getAdjacent(v); 344 345 for(int j=aj->length() - 1; j>=0; j--) 346 { 347 s.push((*aj)[j]); 348 } 349 350 r.add(v); 351 352 visited[v] = true; 353 } 354 } 355 356 ret = toArray(r); 357 } 358 else 359 { 360 THROW_EXCEPTION(InvalidParameterException, "Index i is invalid..."); 361 } 362 363 return ret; 364 } 365 366 SharedPointer<Array<int>> dijkstra(int i, int j, const E& LIMIT) 367 { 368 LinkQueue<int> ret; 369 370 if( (0 <= i) && (i < vCount()) && (0 <= j) && (j < vCount()) ) 371 { 372 DynamicArray<E> dist(vCount()); 373 DynamicArray<int> path(vCount()); 374 DynamicArray<bool> mark(vCount()); 375 376 for(int k=0; k<vCount(); k++) 377 { 378 mark[k] = false; 379 path[k] = -1; 380 381 dist[k] = isAdjacent(i, k) ? (path[k] = i, getEdge(i, k)) : LIMIT; 382 } 383 384 mark[i] = true; 385 386 for(int k=0; k<vCount(); k++) 387 { 388 E m = LIMIT; 389 int u = -1; 390 391 for(int w=0; w<vCount(); w++) 392 { 393 if( !mark[w] && (dist[w] < m) ) 394 { 395 m = dist[w]; 396 u = w; 397 } 398 } 399 400 if( u == -1 ) 401 { 402 break; 403 } 404 405 mark[u] = true; 406 407 for(int w=0; w<vCount(); w++) 408 { 409 if( !mark[w] && isAdjacent(u, w) && (dist[u] + getEdge(u, w) < dist[w]) ) 410 { 411 dist[w] = dist[u] + getEdge(u, w); 412 path[w] = u; 413 } 414 } 415 } 416 417 LinkStack<int> s; 418 419 s.push(j); 420 421 for(int k=path[j]; k != -1; k=path[k]) 422 { 423 s.push(k); 424 } 425 426 while( s.size() > 0 ) 427 { 428 ret.add(s.top()); 429 430 s.pop(); 431 } 432 } 433 else 434 { 435 THROW_EXCEPTION(InvalidParameterException, "Index<i, j> is invalid..."); 436 } 437 438 if( ret.length() < 2 ) 439 { 440 THROW_EXCEPTION(ArithmeticException, "There is no path from i to j..."); 441 } 442 443 return toArray(ret); 444 } 445 446 SharedPointer<Array<int>> floyd(int x, int y, const E& LIMIT) 447 { 448 LinkQueue<int> ret; 449 450 if( (0 <= x) && (x < vCount()) && (0 <= y) && ( y < vCount()) ) 451 { 452 DynamicArray< DynamicArray<E> > dist(vCount()); 453 DynamicArray< DynamicArray<int> > path(vCount()); 454 455 for(int k=0; k<vCount(); k++) 456 { 457 dist[k].resize(vCount()); 458 path[k].resize(vCount()); 459 } 460 461 for(int i = 0; i<vCount(); i++) 462 { 463 for(int j=0; j<vCount(); j++) 464 { 465 path[i][j] = -1; 466 dist[i][j] = isAdjacent(i, j) ? (path[i][j]=j, getEdge(i, j)) : LIMIT; 467 } 468 } 469 470 for(int k=0; k<vCount(); k++) 471 { 472 for(int i = 0; i<vCount(); i++) 473 { 474 for(int j=0; j<vCount(); j++) 475 { 476 if( (dist[i][k] + dist[k][j]) < dist[i][j] ) 477 { 478 dist[i][j] = dist[i][k] + dist[k][j]; 479 path[i][j] = path[i][k]; 480 } 481 } 482 } 483 } 484 485 while( (x != -1) && (x != y) ) 486 { 487 ret.add(x); 488 x = path[x][y]; 489 } 490 491 if( x != -1 ) 492 { 493 ret.add(x); 494 } 495 } 496 else 497 { 498 THROW_EXCEPTION(ArithmeticException, "Index<x, y> is invalid..."); 499 } 500 501 if( ret.length() < 2 ) 502 { 503 THROW_EXCEPTION(ArithmeticException, "There is no path from x to y..."); 504 } 505 506 return toArray(ret); 507 } 508 }; 509 510 } 511 512 #endif // GRAPH_H
测试程序如下:
1 #include <iostream> 2 #include "MatrixGraph.h" 3 #include "ListGraph.h" 4 5 using namespace std; 6 using namespace DTLib; 7 8 template< typename V, typename E > 9 Graph<V, E>& GraphEasy() 10 { 11 static MatrixGraph<4, V, E> g; 12 13 g.setEdge(0, 1, 1); 14 g.setEdge(0, 2, 3); 15 g.setEdge(1, 2, 1); 16 g.setEdge(1, 3, 4); 17 g.setEdge(2, 3, 1); 18 19 return g; 20 } 21 22 template< typename V, typename E > 23 Graph<V, E>& GraphComplex() 24 { 25 static ListGraph<V, E> g(5); 26 27 g.setEdge(0, 1, 10); 28 g.setEdge(0, 3, 30); 29 g.setEdge(0, 4, 100); 30 31 g.setEdge(1, 2, 50); 32 33 g.setEdge(2, 4, 10); 34 35 g.setEdge(3, 2, 20); 36 g.setEdge(3, 4, 60); 37 38 return g; 39 } 40 41 template< typename V, typename E > 42 Graph<V, E>& GraphSample() 43 { 44 static ListGraph<V, E> g(3); 45 46 g.setEdge(0, 1, 4); 47 g.setEdge(0, 2, 11); 48 49 g.setEdge(1, 2, 2); 50 g.setEdge(1, 0, 6); 51 52 g.setEdge(2, 0, 3); 53 54 return g; 55 } 56 57 int main() 58 { 59 Graph<int, int>& g = GraphSample<int, int>(); 60 SharedPointer<Array<int>> r = g.floyd(0, 2, 65536); 61 62 for(int i=0; i<r->length();i++) 63 { 64 cout << (*r)[i] << " "; 65 } 66 67 cout << endl; 68 return 0; 69 }
结果如下:
小结: