00001
00002
00003
00004
00005
00006
00007
00008
00043 #ifdef _MSC_VER
00044 #pragma once
00045 #endif
00046
00047 #ifndef OGDF_SIMPLE_GRAPH_ALG_H
00048 #define OGDF_SIMPLE_GRAPH_ALG_H
00049
00050
00051 #include <ogdf/basic/EdgeArray.h>
00052 #include <ogdf/basic/SList.h>
00053 #include <ogdf/basic/BoundedStack.h>
00054
00055 namespace ogdf {
00056
00057
00058
00059
00060
00061
00063 OGDF_EXPORT bool isLoopFree(const Graph &G);
00064
00066 template<class NODELIST>
00067 void makeLoopFree(Graph &G, NODELIST &L)
00068 {
00069 L.clear();
00070
00071 edge e, eNext;
00072 for (e = G.firstEdge(); e; e = eNext) {
00073 eNext = e->succ();
00074 if (e->isSelfLoop()) {
00075 L.pushBack(e->source());
00076 G.delEdge(e);
00077 }
00078 }
00079 }
00080
00082 OGDF_EXPORT void makeLoopFree(Graph &G);
00083
00084
00085
00086
00087
00088
00089 OGDF_EXPORT void parallelFreeSort(const Graph &G, SListPure<edge> &edges);
00090
00092 OGDF_EXPORT bool isParallelFree(const Graph &G);
00093
00095 OGDF_EXPORT int numParallelEdges(const Graph &G);
00096
00097
00099
00104 template <class EDGELIST>
00105 void makeParallelFree(Graph &G, EDGELIST ¶llelEdges)
00106 {
00107 parallelEdges.clear();
00108 if (G.numberOfEdges() <= 1) return;
00109
00110 SListPure<edge> edges;
00111 parallelFreeSort(G,edges);
00112
00113 SListConstIterator<edge> it = edges.begin();
00114 edge ePrev = *it++, e;
00115 bool bAppend = true;
00116 while(it.valid()) {
00117 e = *it++;
00118 if (ePrev->source() == e->source() && ePrev->target() == e->target()) {
00119 G.delEdge(e);
00120 if (bAppend) { parallelEdges.pushBack(ePrev); bAppend = false; }
00121 } else {
00122 ePrev = e; bAppend = true;
00123 }
00124 }
00125 }
00126
00127
00129 inline void makeParallelFree(Graph &G) {
00130 List<edge> parallelEdges;
00131 makeParallelFree(G,parallelEdges);
00132 }
00133
00134
00135
00136 OGDF_EXPORT void parallelFreeSortUndirected(const Graph &G, SListPure<edge> &edges,
00137 EdgeArray<int> &minIndex, EdgeArray<int> &maxIndex);
00138
00140 OGDF_EXPORT bool isParallelFreeUndirected(const Graph &G);
00141
00143 OGDF_EXPORT int numParallelEdgesUndirected(const Graph &G);
00144
00145
00147
00153 template <class EDGELIST>
00154 void makeParallelFreeUndirected(Graph &G, EDGELIST ¶llelEdges)
00155 {
00156 parallelEdges.clear();
00157 if (G.numberOfEdges() <= 1) return;
00158
00159 SListPure<edge> edges;
00160 EdgeArray<int> minIndex(G), maxIndex(G);
00161 parallelFreeSortUndirected(G,edges,minIndex,maxIndex);
00162
00163 SListConstIterator<edge> it = edges.begin();
00164 edge ePrev = *it++, e;
00165 bool bAppend = true;
00166 while(it.valid()) {
00167 e = *it++;
00168 if (minIndex[ePrev] == minIndex[e] && maxIndex[ePrev] == maxIndex[e]) {
00169 G.delEdge(e);
00170 if (bAppend) { parallelEdges.pushBack(ePrev); bAppend = false; }
00171 } else {
00172 ePrev = e; bAppend = true;
00173 }
00174 }
00175 }
00176
00177
00179
00182 inline void makeParallelFreeUndirected(Graph &G) {
00183 List<edge> parallelEdges;
00184 makeParallelFreeUndirected(G,parallelEdges);
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00195
00205 template <class EDGELIST>
00206 void makeParallelFreeUndirected(Graph &G,
00207 EDGELIST ¶llelEdges,
00208 EdgeArray<int> &cardPositive,
00209 EdgeArray<int> &cardNegative)
00210 {
00211 parallelEdges.clear();
00212 cardPositive.fill(0);
00213 cardNegative.fill(0);
00214 if (G.numberOfEdges() <= 1) return;
00215
00216 SListPure<edge> edges;
00217 EdgeArray<int> minIndex(G), maxIndex(G);
00218 parallelFreeSortUndirected(G,edges,minIndex,maxIndex);
00219
00220 SListConstIterator<edge> it = edges.begin();
00221 edge ePrev = *it++, e;
00222 bool bAppend = true;
00223 int counter = 0;
00224 while(it.valid())
00225 {
00226 e = *it++;
00227 if (minIndex[ePrev] == minIndex[e] && maxIndex[ePrev] == maxIndex[e])
00228 {
00229 if (ePrev->source() == e->source() && ePrev->target() == e->target())
00230 cardPositive[ePrev]++;
00231 else if (ePrev->source() == e->target() && ePrev->target() == e->source())
00232 cardNegative[ePrev]++;
00233 G.delEdge(e);
00234 if (bAppend)
00235 {
00236 parallelEdges.pushBack(ePrev);
00237 bAppend = false;
00238 }
00239 }
00240 else
00241 {
00242 ePrev = e; bAppend = true;
00243 }
00244 }
00245 }
00246
00248
00253 template <class EDGELIST>
00254 void getParallelFreeUndirected(const Graph &G, EdgeArray<EDGELIST> ¶llelEdges)
00255 {
00256 if (G.numberOfEdges() <= 1) return;
00257
00258 SListPure<edge> edges;
00259 EdgeArray<int> minIndex(G), maxIndex(G);
00260 parallelFreeSortUndirected(G,edges,minIndex,maxIndex);
00261
00262 SListConstIterator<edge> it = edges.begin();
00263 edge ePrev = *it++, e;
00264 while(it.valid())
00265 {
00266 e = *it++;
00267 if (minIndex[ePrev] == minIndex[e] && maxIndex[ePrev] == maxIndex[e])
00268 parallelEdges[ePrev].pushBack(e);
00269 else
00270 ePrev = e;
00271 }
00272 }
00273
00274
00275
00276
00277
00278
00280 inline bool isSimple(const Graph &G) {
00281 return isLoopFree(G) && isParallelFree(G);
00282 }
00283
00285 inline void makeSimple(Graph &G) {
00286 makeLoopFree(G);
00287 makeParallelFree(G);
00288 }
00289
00290
00291
00293 inline bool isSimpleUndirected(const Graph &G) {
00294 return isLoopFree(G) && isParallelFreeUndirected(G);
00295 }
00296
00298 inline void makeSimpleUndirected(Graph &G) {
00299 makeLoopFree(G);
00300 makeParallelFreeUndirected(G);
00301 }
00302
00303
00304
00305
00306
00307
00308
00310 OGDF_EXPORT bool isConnected(const Graph &G);
00311
00313
00317 OGDF_EXPORT void makeConnected(Graph &G, List<edge> &added);
00318
00320 inline void makeConnected(Graph &G) {
00321 List<edge> added;
00322 makeConnected(G,added);
00323 }
00324
00326
00333 OGDF_EXPORT int connectedComponents(const Graph &G, NodeArray<int> &component);
00334
00335
00337
00346 OGDF_EXPORT int connectedIsolatedComponents(const Graph &G, List<node> &isolated,
00347 NodeArray<int> &component);
00348
00350
00354 OGDF_EXPORT bool isBiconnected(const Graph &G, node &cutVertex);
00355
00357 inline bool isBiconnected(const Graph &G) {
00358 node cutVertex;
00359 return isBiconnected(G,cutVertex);
00360 }
00361
00363
00367 OGDF_EXPORT void makeBiconnected(Graph &G, List<edge> &added);
00368
00370 inline void makeBiconnected(Graph &G) {
00371 List<edge> added;
00372 makeBiconnected(G,added);
00373 }
00374
00376
00381 OGDF_EXPORT int biconnectedComponents(const Graph &G, EdgeArray<int> &component);
00382
00383
00385
00391 OGDF_EXPORT bool isTriconnected(const Graph &G, node &s1, node &s2);
00392
00394 inline bool isTriconnected(const Graph &G) {
00395 node s1, s2;
00396 return isTriconnected(G,s1,s2);
00397 }
00398
00399
00401
00410 OGDF_EXPORT bool isTriconnectedPrimitive(const Graph &G, node &s1, node &s2);
00411
00413
00417 inline bool isTriconnectedPrimitive(const Graph &G) {
00418 node s1, s2;
00419 return isTriconnectedPrimitive(G,s1,s2);
00420 }
00421
00429 void triangulate(Graph &G);
00430
00431
00432
00433
00434
00436
00440 OGDF_EXPORT bool isAcyclic(const Graph &G, List<edge> &backedges);
00441
00443 inline bool isAcyclic(const Graph &G) {
00444 List<edge> backedges;
00445 return isAcyclic(G,backedges);
00446 }
00447
00449
00453 OGDF_EXPORT bool isAcyclicUndirected(const Graph &G, List<edge> &backedges);
00454
00456 inline bool isAcyclicUndirected(const Graph &G) {
00457 List<edge> backedges;
00458 return isAcyclicUndirected(G,backedges);
00459 }
00460
00462
00465 OGDF_EXPORT void makeAcyclic(Graph &G);
00466
00468
00472 OGDF_EXPORT void makeAcyclicByReverse(Graph &G);
00473
00474
00476
00480 OGDF_EXPORT bool hasSingleSource(const Graph &G, node &source);
00481
00483 inline bool hasSingleSource(const Graph &G) {
00484 node source;
00485 return hasSingleSource(G,source);
00486 }
00487
00489
00493 OGDF_EXPORT bool hasSingleSink(const Graph &G, node &sink);
00494
00495
00496 inline bool hasSingleSink(const Graph &G) {
00497 node sink;
00498 return hasSingleSink(G,sink);
00499 }
00500
00501
00503
00511 OGDF_EXPORT bool isStGraph(const Graph &G, node &s, node &t, edge &st);
00512
00514 inline bool isStGraph(const Graph &G) {
00515 node s, t;
00516 edge st;
00517 return isStGraph(G,s,t,st);
00518 }
00519
00521
00526 OGDF_EXPORT void topologicalNumbering(const Graph &G, NodeArray<int> &num);
00527
00529
00533 OGDF_EXPORT int strongComponents(const Graph& G, NodeArray<int>& component);
00534
00536
00547 void dfsStrongComponents(const Graph& G,
00548 node w,
00549 BoundedStack<node>& S,
00550 NodeArray<int>& pre,
00551 NodeArray<int>& low,
00552 int& cnt,
00553 int& scnt,
00554 NodeArray<int>& component);
00555
00556
00557
00558
00559
00561 OGDF_EXPORT bool isFreeForest(const Graph &G);
00562
00563
00564
00565
00566
00567
00569
00573 OGDF_EXPORT bool isForest(const Graph& G, List<node> &roots);
00574
00576 inline bool isForest(const Graph &G)
00577 {
00578 List<node> roots;
00579 return isForest(G,roots);
00580 }
00581
00583
00587 OGDF_EXPORT bool isTree (const Graph& G, node &root);
00588
00590 inline bool isTree(const Graph &G) {
00591 node root;
00592 return isTree(G,root);
00593 }
00594
00595
00596 }
00597
00598 #endif