6 * $Date: 2012-07-05 16:45:20 +0200 (Do, 05. Jul 2012) $
7 ***************************************************************/
10 * \brief Implementation of class DynamicSPQRForest
12 * \author Jan Papenfuß
15 * This file is part of the Open Graph Drawing Framework (OGDF).
19 * See README.txt in the root directory of the OGDF installation for details.
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * Version 2 or 3 as published by the Free Software Foundation;
25 * see the file LICENSE.txt included in the packaging of this file
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public
36 * License along with this program; if not, write to the Free
37 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
38 * Boston, MA 02110-1301, USA.
40 * \see http://www.gnu.org/copyleft/gpl.html
41 ***************************************************************/
44 #include <ogdf/decomposition/DynamicSPQRForest.h>
45 #include <ogdf/basic/GraphCopy.h>
46 #include "../decomposition/TricComp.h"
52 void DynamicSPQRForest::init ()
54 m_bNode_SPQR
.init(m_B
,0);
55 m_bNode_numS
.init(m_B
,0);
56 m_bNode_numP
.init(m_B
,0);
57 m_bNode_numR
.init(m_B
,0);
58 m_tNode_type
.init(m_T
,SComp
);
59 m_tNode_owner
.init(m_T
);
60 m_tNode_hRefEdge
.init(m_T
);
61 m_tNode_hEdges
.init(m_T
);
62 m_tNode_isMarked
.init(m_T
,false);
63 m_hEdge_position
.init(m_H
);
64 m_hEdge_tNode
.init(m_H
);
65 m_hEdge_twinEdge
.init(m_H
,0);
70 void DynamicSPQRForest::createSPQR (node vB
) const
73 NodeArray
<node
> origNode(GC
,0);
74 EdgeArray
<edge
> origEdge(GC
,0);
75 SListConstIterator
<edge
> iH
;
77 for (iH
=m_bNode_hEdges
[vB
].begin(); iH
.valid(); ++iH
)
78 m_htogc
[(*iH
)->source()] = m_htogc
[(*iH
)->target()] = 0;
80 for (iH
=m_bNode_hEdges
[vB
].begin(); iH
.valid(); ++iH
) {
82 node sH
= eH
->source();
83 node tH
= eH
->target();
84 node
& sGC
= m_htogc
[sH
];
85 node
& tGC
= m_htogc
[tH
];
86 if (!sGC
) { sGC
= GC
.newNode(); origNode
[sGC
] = sH
; }
87 if (!tGC
) { tGC
= GC
.newNode(); origNode
[tGC
] = tH
; }
88 origEdge
[GC
.newEdge(sGC
,tGC
)] = eH
;
91 TricComp
tricComp(GC
);
93 const GraphCopySimple
& GCC
= *tricComp
.m_pGC
;
95 EdgeArray
<node
> partnerNode(GCC
,0);
96 EdgeArray
<edge
> partnerEdge(GCC
,0);
98 for (int i
=0; i
<tricComp
.m_numComp
; ++i
) {
99 const TricComp::CompStruct
&C
= tricComp
.m_component
[i
];
101 if (C
.m_edges
.empty()) continue;
103 node vT
= m_T
.newNode();
104 m_tNode_owner
[vT
] = vT
;
108 m_tNode_type
[vT
] = PComp
;
111 case TricComp::polygon
:
112 m_tNode_type
[vT
] = SComp
;
115 case TricComp::triconnected
:
116 m_tNode_type
[vT
] = RComp
;
121 for (ListConstIterator
<edge
> iGCC
=C
.m_edges
.begin(); iGCC
.valid(); ++iGCC
) {
123 edge eH
= GCC
.original(eGCC
);
124 if (eH
) eH
= origEdge
[eH
];
126 node uH
= origNode
[GCC
.original(eGCC
->source())];
127 node vH
= origNode
[GCC
.original(eGCC
->target())];
128 eH
= m_H
.newEdge(uH
,vH
);
130 if (!partnerNode
[eGCC
]) {
131 partnerNode
[eGCC
] = vT
;
132 partnerEdge
[eGCC
] = eH
;
135 m_T
.newEdge(partnerNode
[eGCC
],vT
);
136 m_hEdge_twinEdge
[eH
] = partnerEdge
[eGCC
];
137 m_hEdge_twinEdge
[partnerEdge
[eGCC
]] = eH
;
140 m_hEdge_position
[eH
] = m_tNode_hEdges
[vT
].pushBack(eH
);
141 m_hEdge_tNode
[eH
] = vT
;
145 m_bNode_SPQR
[vB
] = m_hEdge_tNode
[origEdge
[GC
.firstEdge()]];
146 m_tNode_hRefEdge
[m_bNode_SPQR
[vB
]] = 0;
149 lT
.pushBack(m_bNode_SPQR
[vB
]);
151 while (!lT
.empty()) {
152 node vT
= lT
.popFrontRet();
153 node wT
= lT
.popFrontRet();
154 for (ListConstIterator
<edge
> iH
=m_tNode_hEdges
[vT
].begin(); iH
.valid(); ++iH
) {
156 edge fH
= m_hEdge_twinEdge
[eH
];
158 node uT
= m_hEdge_tNode
[fH
];
159 if (uT
==wT
) m_tNode_hRefEdge
[vT
] = eH
;
169 node
DynamicSPQRForest::uniteSPQR (node vB
, node sT
, node tT
)
171 if (m_tNode_type
[tT
]==SComp
) m_bNode_numS
[vB
]--;
172 else if (m_tNode_type
[tT
]==PComp
) m_bNode_numP
[vB
]--;
173 else if (m_tNode_type
[tT
]==RComp
) m_bNode_numR
[vB
]--;
179 if (m_tNode_hEdges
[sT
].size()<m_tNode_hEdges
[tT
].size()) { node uT
= sT
; sT
= tT
; tT
= uT
; }
180 m_tNode_owner
[tT
] = sT
;
181 m_tNode_hEdges
[sT
].conc(m_tNode_hEdges
[tT
]);
183 m_tNode_type
[sT
] = RComp
;
188 node
DynamicSPQRForest::findSPQR (node vT
) const
191 if (m_tNode_owner
[vT
]==vT
) return vT
;
192 return m_tNode_owner
[vT
] = findSPQR(m_tNode_owner
[vT
]);
196 node
DynamicSPQRForest::findNCASPQR (node sT
, node tT
) const
198 if (m_tNode_isMarked
[sT
]) return sT
;
199 m_tNode_isMarked
[sT
] = true;
200 node uT
= m_tNode_hRefEdge
[sT
] ? spqrproper(m_hEdge_twinEdge
[m_tNode_hRefEdge
[sT
]]) : 0;
201 if (uT
) uT
= findNCASPQR(tT
,uT
);
202 else for (uT
=tT
; !m_tNode_isMarked
[uT
]; uT
=spqrproper(m_hEdge_twinEdge
[m_tNode_hRefEdge
[uT
]]));
203 m_tNode_isMarked
[sT
] = false;
208 SList
<node
>& DynamicSPQRForest::findPathSPQR (node sH
, node tH
, node
& rT
) const
210 SList
<node
>& pT
= *OGDF_NEW SList
<node
>;
211 node sT
= spqrproper(sH
->firstAdj()->theEdge());
212 node tT
= spqrproper(tH
->firstAdj()->theEdge());
213 node nT
= findNCASPQR(sT
,tT
);
215 edge eH
= m_tNode_hRefEdge
[sT
];
216 node uH
= eH
->source();
217 node vH
= eH
->target();
218 if (uH
!=sH
&& vH
!=sH
) pT
.pushBack(sT
);
219 if (uH
==tH
|| vH
==tH
) { rT
= sT
; return pT
; }
220 sT
= spqrproper(m_hEdge_twinEdge
[eH
]);
222 SListIterator
<node
> iT
= pT
.rbegin();
224 edge eH
= m_tNode_hRefEdge
[tT
];
225 node uH
= eH
->source();
226 node vH
= eH
->target();
227 if (uH
!=tH
&& vH
!=tH
) {
228 if (iT
.valid()) pT
.insertAfter(tT
,iT
);
229 else pT
.pushFront(tT
);
231 if (uH
==sH
|| vH
==sH
) { rT
= tT
; return pT
; }
232 tT
= spqrproper(m_hEdge_twinEdge
[eH
]);
234 if (iT
.valid()) pT
.insertAfter(nT
,iT
);
235 else pT
.pushFront(nT
);
240 SList
<node
>& DynamicSPQRForest::findPathSPQR (node sH
, node tH
) const
242 node vB
= bComponent(m_hNode_gNode
[sH
],m_hNode_gNode
[tH
]);
243 if (!vB
) return *OGDF_NEW SList
<node
>;
244 if (!m_bNode_SPQR
[vB
]) {
245 if (m_bNode_hEdges
[vB
].size()<3) return *OGDF_NEW SList
<node
>;
249 SList
<node
>& pT
= findPathSPQR(sH
,tH
,rT
);
250 if (pT
.empty()) if (rT
) pT
.pushBack(rT
);
255 edge
DynamicSPQRForest::virtualEdge (node vT
, node wT
) const
257 edge eH
= m_tNode_hRefEdge
[vT
];
259 eH
= m_hEdge_twinEdge
[eH
];
260 if (spqrproper(eH
)==wT
) return eH
;
262 eH
= m_tNode_hRefEdge
[wT
];
264 if (spqrproper(m_hEdge_twinEdge
[eH
])==vT
) return eH
;
270 edge
DynamicSPQRForest::updateInsertedEdgeSPQR (node vB
, edge eG
)
272 node sG
= eG
->source();
273 node tG
= eG
->target();
274 node sH
= repVertex(sG
,vB
);
275 node tH
= repVertex(tG
,vB
);
276 edge eH
= m_H
.newEdge(sH
,tH
);
277 m_gEdge_hEdge
[eG
] = eH
;
278 m_hEdge_gEdge
[eH
] = eG
;
282 edge fH
= aH
->theEdge();
283 if (fH
==eH
) continue;
284 if (fH
->opposite(sH
)!=tH
) continue;
285 node vT
= spqrproper(fH
);
286 if (m_tNode_type
[vT
]==PComp
) {
287 m_hEdge_position
[eH
] = m_tNode_hEdges
[vT
].pushBack(eH
);
288 m_hEdge_tNode
[eH
] = vT
;
291 edge gH
= m_hEdge_twinEdge
[fH
];
294 node nT
= m_T
.newNode();
295 m_tNode_type
[nT
] = PComp
;
296 m_tNode_owner
[nT
] = nT
;
297 edge v1
= m_H
.newEdge(sH
,tH
);
298 edge v2
= m_H
.newEdge(sH
,tH
);
299 m_hEdge_position
[v1
] = m_tNode_hEdges
[vT
].insertAfter(v1
,m_hEdge_position
[fH
]);
300 m_tNode_hEdges
[vT
].del(m_hEdge_position
[fH
]);
301 m_hEdge_position
[v2
] = m_tNode_hEdges
[nT
].pushBack(v2
);
302 m_hEdge_position
[fH
] = m_tNode_hEdges
[nT
].pushBack(fH
);
303 m_hEdge_position
[eH
] = m_tNode_hEdges
[nT
].pushBack(eH
);
304 m_hEdge_tNode
[v1
] = vT
;
305 m_hEdge_twinEdge
[v1
] = m_tNode_hRefEdge
[nT
] = v2
;
306 m_hEdge_tNode
[v2
] = m_hEdge_tNode
[eH
] = m_hEdge_tNode
[fH
] = nT
;
307 m_hEdge_twinEdge
[v2
] = v1
;
310 node wT
= spqrproper(gH
);
311 if (m_tNode_type
[wT
]==PComp
) {
312 m_hEdge_position
[eH
] = m_tNode_hEdges
[vT
].pushBack(eH
);
313 m_hEdge_tNode
[eH
] = vT
;
317 node nT
= m_T
.newNode();
318 m_tNode_type
[nT
] = PComp
;
319 m_tNode_owner
[nT
] = nT
;
320 edge v1
= m_tNode_hRefEdge
[vT
];
321 if (!v1
) v1
= m_tNode_hRefEdge
[wT
];
322 else if (spqrproper(m_hEdge_twinEdge
[v1
])!=wT
) v1
= m_tNode_hRefEdge
[wT
];
323 edge v4
= m_hEdge_twinEdge
[v1
];
324 edge v2
= m_H
.newEdge(v1
->source(),v1
->target());
325 edge v3
= m_H
.newEdge(v4
->source(),v4
->target());
326 m_hEdge_twinEdge
[v1
] = v2
;
327 m_hEdge_twinEdge
[v2
] = v1
;
328 m_hEdge_twinEdge
[v3
] = v4
;
329 m_hEdge_twinEdge
[v4
] = v3
;
330 m_hEdge_position
[v2
] = m_tNode_hEdges
[nT
].pushBack(v2
);
331 m_hEdge_position
[eH
] = m_tNode_hEdges
[nT
].pushBack(eH
);
332 m_hEdge_position
[v3
] = m_tNode_hEdges
[nT
].pushBack(v3
);
333 m_hEdge_tNode
[v2
] = m_hEdge_tNode
[eH
] = m_hEdge_tNode
[v3
] = nT
;
334 m_tNode_hRefEdge
[nT
] = v3
;
340 SList
<node
>& pT
= findPathSPQR(sH
,tH
,rT
);
342 if (m_tNode_type
[rT
]==RComp
) {
343 m_hEdge_position
[eH
] = m_tNode_hEdges
[rT
].pushBack(eH
);
344 m_hEdge_tNode
[eH
] = rT
;
347 List
<edge
>& aH
= m_tNode_hEdges
[rT
];
349 bool a_is_parent
= true;
350 ListIterator
<edge
> iH
= aH
.begin();
353 node xH
= (*iH
)->source();
354 node yH
= (*iH
)->target();
356 else if (yH
==uH
) uH
= xH
;
357 else { iH
= aH
.cyclicSucc(iH
); continue; }
358 if (*iH
==m_tNode_hRefEdge
[rT
]) a_is_parent
= false;
360 ListIterator
<edge
> jH
= iH
;
361 iH
= aH
.cyclicSucc(iH
);
366 node sT
= m_T
.newNode();
367 node pT
= m_T
.newNode();
368 m_tNode_type
[sT
] = SComp
;
369 m_tNode_type
[pT
] = PComp
;
370 m_tNode_owner
[sT
] = sT
;
371 m_tNode_owner
[pT
] = pT
;
372 edge v1
= m_H
.newEdge(sH
,tH
);
373 edge v2
= m_H
.newEdge(sH
,tH
);
374 edge v3
= m_H
.newEdge(sH
,tH
);
375 edge v4
= m_H
.newEdge(sH
,tH
);
376 m_hEdge_twinEdge
[v1
] = v2
;
377 m_hEdge_twinEdge
[v2
] = v1
;
378 m_hEdge_twinEdge
[v3
] = v4
;
379 m_hEdge_twinEdge
[v4
] = v3
;
380 m_hEdge_position
[v1
] = m_tNode_hEdges
[sT
].pushBack(v1
);
381 m_hEdge_position
[v2
] = m_tNode_hEdges
[pT
].pushBack(v2
);
382 m_hEdge_position
[eH
] = m_tNode_hEdges
[pT
].pushBack(eH
);
383 m_hEdge_position
[v3
] = m_tNode_hEdges
[pT
].pushBack(v3
);
384 m_hEdge_position
[v4
] = m_tNode_hEdges
[rT
].pushBack(v4
);
385 m_hEdge_tNode
[v1
] = sT
;
386 m_hEdge_tNode
[v2
] = m_hEdge_tNode
[eH
] = m_hEdge_tNode
[v3
] = pT
;
387 m_hEdge_tNode
[v4
] = rT
;
388 for (SListConstIterator
<edge
> iH
=bH
.begin(); iH
.valid(); ++iH
) {
389 m_hEdge_position
[*iH
] = m_tNode_hEdges
[sT
].pushBack(*iH
);
390 m_hEdge_tNode
[*iH
] = sT
;
393 m_tNode_hRefEdge
[sT
] = v1
;
394 m_tNode_hRefEdge
[pT
] = v3
;
397 m_tNode_hRefEdge
[sT
] = m_tNode_hRefEdge
[rT
];
398 m_tNode_hRefEdge
[pT
] = v2
;
399 m_tNode_hRefEdge
[rT
] = v4
;
400 if (!m_tNode_hRefEdge
[sT
]) m_bNode_SPQR
[vB
] = sT
;
406 SList
<edge
> absorbedEdges
;
407 SList
<edge
> virtualEdgesInPath
;
408 SList
<edge
> newVirtualEdges
;
410 edge rH
= m_tNode_hRefEdge
[rT
];
412 SListIterator
<node
> iT
= pT
.begin();
413 SListIterator
<node
> jT
= iT
;
415 virtualEdgesInPath
.pushBack(0);
416 for (++jT
; jT
.valid(); ++iT
, ++jT
) {
417 edge gH
,fH
= m_tNode_hRefEdge
[*iT
];
419 gH
= m_tNode_hRefEdge
[*jT
];
420 fH
= m_hEdge_twinEdge
[gH
];
423 gH
= m_hEdge_twinEdge
[fH
];
424 if (spqrproper(gH
)!=*jT
) {
425 gH
= m_tNode_hRefEdge
[*jT
];
426 fH
= m_hEdge_twinEdge
[gH
];
429 virtualEdgesInPath
.pushBack(fH
);
430 virtualEdgesInPath
.pushBack(gH
);
432 virtualEdgesInPath
.pushBack(0);
434 for (iT
=pT
.begin(); iT
.valid(); ++iT
) {
435 edge fH
= virtualEdgesInPath
.popFrontRet();
436 edge gH
= virtualEdgesInPath
.popFrontRet();
437 if (m_tNode_type
[*iT
]==SComp
) {
438 List
<edge
>& aH
= m_tNode_hEdges
[*iT
];
440 ListIterator
<edge
> iH
,jH
;
444 if (!fH
) { fH
= gH
; uH
= sH
; }
445 else if (!gH
) uH
= tH
;
447 node vH
= fH
->source();
448 node wH
= fH
->target();
451 iH
= jH
= m_hEdge_position
[fH
];
453 iH
= aH
.cyclicSucc(iH
);
454 node xH
= (*iH
)->source();
455 node yH
= (*iH
)->target();
456 if (xH
==vH
) { zH
= vH
; vH
= yH
; break; }
457 if (xH
==wH
) { zH
= wH
; wH
= vH
; vH
= yH
; break; }
458 if (yH
==vH
) { zH
= vH
; vH
= xH
; break; }
459 if (yH
==wH
) { zH
= wH
; wH
= vH
; vH
= xH
; break; }
464 iH
= aH
.cyclicSucc(iH
);
469 node xH
= (*iH
)->source();
470 node yH
= (*iH
)->target();
471 if (xH
==vH
) { vH
= yH
; break; }
472 if (yH
==vH
) { vH
= xH
; break; }
473 iH
= aH
.cyclicSucc(iH
);
476 iH
= aH
.cyclicSucc(iH
);
481 edge nH
= bH
.front();
483 absorbedEdges
.pushBack(nH
);
487 node nT
= m_T
.newNode();
488 m_tNode_type
[nT
] = SComp
;
489 m_tNode_owner
[nT
] = nT
;
490 while (!bH
.empty()) {
491 edge nH
= bH
.popFrontRet();
492 m_hEdge_position
[nH
] = m_tNode_hEdges
[nT
].pushBack(nH
);
493 m_hEdge_tNode
[nH
] = nT
;
496 edge nH
= m_H
.newEdge(vH
,zH
);
497 m_hEdge_position
[nH
] = m_tNode_hEdges
[nT
].pushBack(nH
);
498 m_hEdge_tNode
[nH
] = nT
;
500 m_tNode_hRefEdge
[nT
] = rH
;
501 if (!rH
) m_bNode_SPQR
[vB
] = nT
;
504 else m_tNode_hRefEdge
[nT
] = nH
;
505 newVirtualEdges
.pushBack(nH
);
507 if (m_tNode_hEdges
[*iT
].size()==1) xT
= uniteSPQR(vB
,xT
,*iT
);
509 edge nH
= m_H
.newEdge(wH
,vH
);
510 m_hEdge_position
[nH
] = m_tNode_hEdges
[*iT
].pushBack(nH
);
511 m_hEdge_tNode
[nH
] = *iT
;
512 if (*iT
==rT
) rH
= nH
;
513 else m_tNode_hRefEdge
[*iT
] = nH
;
514 newVirtualEdges
.pushBack(nH
);
517 else if (aH
.size()==3) {
518 aH
.del(m_hEdge_position
[fH
]);
519 aH
.del(m_hEdge_position
[gH
]);
522 xT
= uniteSPQR(vB
,xT
,*iT
);
525 node xH
= gH
->source();
526 node yH
= gH
->target();
528 if (vH
==xH
) nH
= m_H
.newEdge(wH
,yH
);
529 else if (vH
==yH
) nH
= m_H
.newEdge(wH
,xH
);
530 else if (wH
==xH
) nH
= m_H
.newEdge(vH
,yH
);
531 else if (wH
==yH
) nH
= m_H
.newEdge(vH
,xH
);
533 m_hEdge_position
[nH
] = aH
.insertAfter(nH
,m_hEdge_position
[gH
]);
534 m_hEdge_tNode
[nH
] = *iT
;
535 if (*iT
==rT
) rH
= nH
;
536 else m_tNode_hRefEdge
[*iT
] = nH
;
537 aH
.del(m_hEdge_position
[fH
]);
538 aH
.del(m_hEdge_position
[gH
]);
541 newVirtualEdges
.pushBack(nH
);
544 iH
= jH
= m_hEdge_position
[fH
];
546 iH
= aH
.cyclicSucc(iH
);
547 node xH
= (*iH
)->source();
548 node yH
= (*iH
)->target();
549 if (xH
==vH
) { zH
= vH
; vH
= yH
; break; }
550 if (xH
==wH
) { zH
= wH
; wH
= vH
; vH
= yH
; break; }
551 if (yH
==vH
) { zH
= vH
; vH
= xH
; break; }
552 if (yH
==wH
) { zH
= wH
; wH
= vH
; vH
= xH
; break; }
557 iH
= aH
.cyclicSucc(iH
);
560 node pH
= gH
->source();
561 node qH
= gH
->target();
562 while (vH
!=pH
&& vH
!=qH
) {
564 node xH
= (*iH
)->source();
565 node yH
= (*iH
)->target();
566 if (xH
==vH
) { vH
= yH
; break; }
567 if (yH
==vH
) { vH
= xH
; break; }
568 iH
= aH
.cyclicSucc(iH
);
571 iH
= aH
.cyclicSucc(iH
);
575 aH
.del(m_hEdge_position
[gH
]);
578 edge nH
= bH
.front();
580 absorbedEdges
.pushBack(nH
);
584 node nT
= m_T
.newNode();
585 m_tNode_type
[nT
] = SComp
;
586 m_tNode_owner
[nT
] = nT
;
587 while (!bH
.empty()) {
588 edge nH
= bH
.popFrontRet();
589 m_hEdge_position
[nH
] = m_tNode_hEdges
[nT
].pushBack(nH
);
590 m_hEdge_tNode
[nH
] = nT
;
593 edge nH
= m_H
.newEdge(vH
,zH
);
594 m_hEdge_position
[nH
] = m_tNode_hEdges
[nT
].pushBack(nH
);
595 m_hEdge_tNode
[nH
] = nT
;
597 m_tNode_hRefEdge
[nT
] = rH
;
598 if (!rH
) m_bNode_SPQR
[vB
] = nT
;
601 else m_tNode_hRefEdge
[nT
] = nH
;
602 newVirtualEdges
.pushBack(nH
);
604 if (m_tNode_hEdges
[*iT
].size()==1) xT
= uniteSPQR(vB
,xT
,*iT
);
606 edge nH
= m_H
.newEdge(wH
,vH
==pH
?qH
:pH
);
607 m_hEdge_position
[nH
] = m_tNode_hEdges
[*iT
].pushBack(nH
);
608 m_hEdge_tNode
[nH
] = *iT
;
609 if (*iT
==rT
) rH
= nH
;
610 else m_tNode_hRefEdge
[*iT
] = nH
;
611 newVirtualEdges
.pushBack(nH
);
618 m_tNode_hEdges
[*iT
].del(m_hEdge_position
[fH
]);
622 m_tNode_hEdges
[*iT
].del(m_hEdge_position
[gH
]);
625 if (m_tNode_type
[*iT
]==PComp
) {
626 if (m_tNode_hEdges
[*iT
].size()>1) {
627 edge nH
= m_tNode_hEdges
[*iT
].front();
628 nH
= m_H
.newEdge(nH
->source(),nH
->target());
629 m_hEdge_position
[nH
] = m_tNode_hEdges
[*iT
].pushBack(nH
);
630 m_hEdge_tNode
[nH
] = *iT
;
631 if (*iT
==rT
) rH
= nH
;
632 else m_tNode_hRefEdge
[*iT
] = nH
;
633 newVirtualEdges
.pushBack(nH
);
635 else xT
= uniteSPQR(vB
,xT
,*iT
);
637 else xT
= uniteSPQR(vB
,xT
,*iT
);
643 m_tNode_type
[xT
] = RComp
;
644 m_tNode_owner
[xT
] = xT
;
646 while (!newVirtualEdges
.empty()) {
647 edge oH
= newVirtualEdges
.popFrontRet();
648 edge nH
= m_H
.newEdge(oH
->source(),oH
->target());
649 m_hEdge_position
[nH
] = m_tNode_hEdges
[xT
].pushBack(nH
);
650 m_hEdge_tNode
[nH
] = xT
;
651 m_hEdge_twinEdge
[nH
] = oH
;
652 m_hEdge_twinEdge
[oH
] = nH
;
654 while (!absorbedEdges
.empty()) {
655 edge nH
= absorbedEdges
.popFrontRet();
656 m_hEdge_position
[nH
] = m_tNode_hEdges
[xT
].pushBack(nH
);
657 m_hEdge_tNode
[nH
] = xT
;
659 m_hEdge_position
[eH
] = m_tNode_hEdges
[xT
].pushBack(eH
);
660 m_hEdge_tNode
[eH
] = xT
;
661 if (!rT
) m_tNode_hRefEdge
[xT
] = rH
;
662 else if (findSPQR(rT
)!=xT
) m_tNode_hRefEdge
[xT
] = m_hEdge_twinEdge
[rH
];
664 m_tNode_hRefEdge
[xT
] = rH
;
665 if (!rH
) m_bNode_SPQR
[vB
] = xT
;
673 node
DynamicSPQRForest::updateInsertedNodeSPQR (node vB
, edge eG
, edge fG
)
675 node vG
= fG
->source();
676 node wG
= fG
->target();
677 node vH
= m_H
.newNode();
678 node wH
= repVertex(wG
,vB
);
679 m_gNode_hNode
[vG
] = vH
;
680 m_hNode_gNode
[vH
] = vG
;
681 edge fH
= m_H
.newEdge(vH
,wH
);
682 m_gEdge_hEdge
[fG
] = fH
;
683 m_hEdge_gEdge
[fH
] = fG
;
684 edge eH
= m_gEdge_hEdge
[eG
];
685 m_H
.moveTarget(eH
,vH
);
686 node vT
= spqrproper(eH
);
687 if (m_tNode_type
[vT
]==SComp
) {
688 m_hEdge_position
[fH
] = m_tNode_hEdges
[vT
].insertAfter(fH
,m_hEdge_position
[eH
]);
689 m_hEdge_tNode
[fH
] = vT
;
693 node nT
= m_T
.newNode();
694 m_tNode_type
[nT
] = SComp
;
695 m_tNode_owner
[nT
] = nT
;
696 node uH
= eH
->source();
697 node wH
= fH
->target();
698 edge v1
= m_H
.newEdge(uH
,wH
);
699 edge v2
= m_H
.newEdge(uH
,wH
);
700 m_hEdge_position
[v1
] = m_tNode_hEdges
[vT
].insertAfter(v1
,m_hEdge_position
[eH
]);
701 m_tNode_hEdges
[vT
].del(m_hEdge_position
[eH
]);
702 m_hEdge_position
[v2
] = m_tNode_hEdges
[nT
].pushBack(v2
);
703 m_hEdge_position
[eH
] = m_tNode_hEdges
[nT
].pushBack(eH
);
704 m_hEdge_position
[fH
] = m_tNode_hEdges
[nT
].pushBack(fH
);
705 m_hEdge_tNode
[v1
] = vT
;
706 m_hEdge_twinEdge
[v1
] = m_tNode_hRefEdge
[nT
] = v2
;
707 m_hEdge_tNode
[v2
] = m_hEdge_tNode
[eH
] = m_hEdge_tNode
[fH
] = nT
;
708 m_hEdge_twinEdge
[v2
] = v1
;
714 edge
DynamicSPQRForest::updateInsertedEdge (edge eG
)
716 node sG
= eG
->source();
717 node tG
= eG
->target();
718 node vB
= bComponent(sG
,tG
);
720 if (m_bNode_SPQR
[vB
]) {
721 edge eH
= m_gEdge_hEdge
[updateInsertedEdgeSPQR(vB
,eG
)];
722 m_bNode_hEdges
[vB
].pushBack(eH
);
723 m_hEdge_bNode
[eH
] = vB
;
725 else DynamicBCTree::updateInsertedEdge(eG
);
730 SList
<node
>& pB
= findPath(sG
,tG
);
731 SListIterator
<node
> jB
= pB
.begin();
732 SListIterator
<node
> iB
= jB
;
733 while (iB
.valid()) { if (m_bNode_SPQR
[*iB
]) break; ++iB
; }
736 m_tNode_type
[nT
] = SComp
;
737 m_tNode_owner
[nT
] = nT
;
738 m_tNode_hRefEdge
[nT
] = 0;
742 node sH
= repVertex(sG
,*jB
);
743 for (iB
=jB
; iB
.valid(); ++iB
) {
744 node tH
= (++jB
).valid() ? cutVertex(*jB
,*iB
) : repVertex(tG
,*iB
);
747 switch (numberOfEdges(*iB
)) {
751 nH
= m_bNode_hEdges
[*iB
].front();
752 m_hEdge_position
[nH
] = m_tNode_hEdges
[nT
].pushBack(nH
);
753 m_hEdge_tNode
[nH
] = nT
;
757 m_tNode_type
[mT
] = PComp
;
758 m_tNode_owner
[mT
] = mT
;
759 mH
= m_bNode_hEdges
[*iB
].front();
760 m_hEdge_position
[mH
] = m_tNode_hEdges
[mT
].pushBack(mH
);
761 m_hEdge_tNode
[mH
] = mT
;
762 mH
= m_bNode_hEdges
[*iB
].back();
763 m_hEdge_position
[mH
] = m_tNode_hEdges
[mT
].pushBack(mH
);
764 m_hEdge_tNode
[mH
] = mT
;
765 mH
= m_H
.newEdge(sH
,tH
);
766 m_hEdge_position
[mH
] = m_tNode_hEdges
[mT
].pushBack(mH
);
767 m_hEdge_tNode
[mH
] = mT
;
768 nH
= m_H
.newEdge(sH
,tH
);
769 m_hEdge_position
[nH
] = m_tNode_hEdges
[nT
].pushBack(nH
);
770 m_hEdge_tNode
[nH
] = nT
;
771 m_hEdge_twinEdge
[mH
] = nH
;
772 m_hEdge_twinEdge
[nH
] = mH
;
773 m_tNode_hRefEdge
[mT
] = mH
;
777 if (!m_bNode_SPQR
[*iB
]) createSPQR(*iB
);
778 edge mG
= m_G
.newEdge(m_hNode_gNode
[sH
],m_hNode_gNode
[tH
]);
779 updateInsertedEdgeSPQR(*iB
,mG
);
780 mH
= m_gEdge_hEdge
[mG
];
783 m_hEdge_gEdge
[mH
] = 0;
784 nH
= m_H
.newEdge(sH
,tH
);
785 m_hEdge_position
[nH
] = m_tNode_hEdges
[nT
].pushBack(nH
);
786 m_hEdge_tNode
[nH
] = nT
;
787 m_hEdge_twinEdge
[mH
] = nH
;
788 m_hEdge_twinEdge
[nH
] = mH
;
790 nH
= m_tNode_hRefEdge
[mT
];
791 m_tNode_hRefEdge
[mT
] = mH
;
793 mH
= m_hEdge_twinEdge
[nH
];
796 numS
+= m_bNode_numS
[*iB
];
797 numP
+= m_bNode_numP
[*iB
];
798 numR
+= m_bNode_numR
[*iB
];
800 if (jB
.valid()) sH
= cutVertex(*iB
,*jB
);
804 DynamicBCTree::updateInsertedEdge(eG
);
806 edge eH
= m_gEdge_hEdge
[eG
];
807 m_hEdge_position
[eH
] = m_tNode_hEdges
[nT
].pushBack(eH
);
808 m_hEdge_tNode
[eH
] = nT
;
809 node eB
= bcproper(eG
);
810 m_bNode_SPQR
[eB
] = nT
;
811 m_bNode_numS
[eB
] = numS
;
812 m_bNode_numP
[eB
] = numP
;
813 m_bNode_numR
[eB
] = numR
;
820 node
DynamicSPQRForest::updateInsertedNode (edge eG
, edge fG
)
822 node vB
= bcproper(eG
);
823 if (m_bNode_SPQR
[vB
]) {
824 node uG
= updateInsertedNodeSPQR(vB
,eG
,fG
);
825 m_gNode_isMarked
[uG
] = false;
826 edge fH
= m_gEdge_hEdge
[fG
];
827 m_bNode_hEdges
[vB
].pushBack(fH
);
828 m_hEdge_bNode
[fH
] = vB
;
829 m_hNode_bNode
[fH
->source()] = vB
;
830 m_bNode_numNodes
[vB
]++;
833 return DynamicBCTree::updateInsertedNode(eG
,fG
);