Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
cut_nodes_test.cc
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
38#include <gtest/gtest.h>
39
40#include <set>
41#include <vector>
42
43#include <tpl_cut_nodes.H>
44#include <tpl_graph.H>
45#include <tpl_graph_utils.H>
46
47using namespace Aleph;
48
49namespace
50{
52
53 std::vector<Graph::Node *> make_nodes(Graph & g, int n)
54 {
55 std::vector<Graph::Node *> nodes;
56 nodes.reserve(n);
57 for (int i = 0; i < n; ++i)
58 nodes.push_back(g.insert_node(i));
59 return nodes;
60 }
61
62 std::set<int> cut_infos(const DynDlist<Graph::Node *> & list)
63 {
64 std::set<int> s;
65 for (typename DynDlist<Graph::Node *>::Iterator it(list); it.has_curr(); it.next_ne())
66 s.insert(it.get_curr()->get_info());
67 return s;
68 }
69
70 size_t count_nodes_with_color(const Graph & g, long color)
71 {
72 size_t n = 0;
73 for (auto it = g.get_node_it(); it.has_curr(); it.next_ne())
74 {
75 auto p = it.get_curr();
76 if (get_color<Graph>(p) == color)
77 ++n;
78 }
79 return n;
80 }
81
82 size_t count_arcs_with_color(const Graph & g, long color)
83 {
84 size_t n = 0;
85 for (auto it = g.get_arc_it(); it.has_curr(); it.next_ne())
86 {
87 auto a = it.get_curr();
88 if (get_color<Graph>(a) == color)
89 ++n;
90 }
91 return n;
92 }
93
94 size_t count_cut_arcs(const Graph & g)
95 {
96 size_t n = 0;
97 for (auto it = g.get_arc_it(); it.has_curr(); it.next_ne())
98 if (is_an_cut_arc<Graph>(it.get_curr()))
99 ++n;
100 return n;
101 }
102
103} // namespace
104
106{
107 Graph g;
108 auto nodes = make_nodes(g, 4);
109 g.insert_arc(nodes[0], nodes[1], 1);
110 g.insert_arc(nodes[1], nodes[2], 1);
111 g.insert_arc(nodes[2], nodes[3], 1);
112
115 alg(nodes[0], cuts);
116
117 EXPECT_EQ(cut_infos(cuts), (std::set<int>{1, 2}));
118}
119
121{
122 Graph g;
123 auto nodes = make_nodes(g, 4);
124 g.insert_arc(nodes[0], nodes[1], 1);
125 g.insert_arc(nodes[1], nodes[2], 1);
126 g.insert_arc(nodes[2], nodes[3], 1);
127 g.insert_arc(nodes[3], nodes[0], 1);
128
131 alg(nodes[0], cuts);
132
134}
135
137{
138 Graph g;
139 auto nodes = make_nodes(g, 6);
140 const int center = 0;
141 for (int i = 1; i < 6; ++i)
142 g.insert_arc(nodes[center], nodes[i], 1);
143
146 alg(nodes[center], cuts);
147
148 EXPECT_EQ(cut_infos(cuts), (std::set<int>{0}));
149}
150
152{
153 Graph g;
154 auto nodes = make_nodes(g, 2);
155 g.insert_arc(nodes[0], nodes[1], 1);
156
159
160 EXPECT_THROW((void)alg.paint_subgraphs(), std::logic_error);
161}
162
164{
165 Graph g;
166 auto nodes = make_nodes(g, 5);
167 for (int i = 1; i < 5; ++i)
168 g.insert_arc(nodes[0], nodes[i], 1);
169
172 alg(nodes[0], cuts);
173
174 const long next_color = alg.paint_subgraphs();
175 EXPECT_EQ(next_color, 5L); // 4 leaf blocks => colors 1..4, next=5
176
179 for (int i = 1; i < 5; ++i)
181
184 alg.map_cut_graph(cut_graph, cross);
185
186 EXPECT_EQ(cut_graph.get_num_nodes(), 1U);
187 EXPECT_EQ(cut_graph.get_num_arcs(), 0U);
188
190 for (typename DynDlist<Graph::Arc *>::Iterator it(cross); it.has_curr(); it.next_ne())
191 EXPECT_TRUE(is_a_cross_arc<Graph>(it.get_curr()));
192}
193
195{
196 Graph g;
197 auto nodes = make_nodes(g, 5);
198 for (int i = 1; i < 5; ++i)
199 g.insert_arc(nodes[0], nodes[i], 1);
200
203 alg(nodes[0], cuts);
204 (void)alg.paint_subgraphs();
205
206 // In this star, colors 1..4 correspond to single-node blocks.
207 for (long color = 1; color <= 4; ++color)
208 {
209 Graph sg;
210 alg.map_subgraph(sg, color);
211
214 }
215}
216
218{
219 Graph g;
220 auto nodes = make_nodes(g, 4);
221 g.insert_arc(nodes[0], nodes[1], 1);
222 g.insert_arc(nodes[1], nodes[2], 1);
223 g.insert_arc(nodes[2], nodes[3], 1);
224
227 alg(nodes[0], cuts);
228 (void)alg.paint_subgraphs();
229
232 alg.map_cut_graph(cut_graph, cross);
233
234 EXPECT_EQ(cut_graph.get_num_nodes(), cuts.size());
235 EXPECT_EQ(cut_graph.get_num_arcs(), count_cut_arcs(g));
236}
237
238// ============================================================================
239// Additional Graph Topologies
240// ============================================================================
241
243{
244 Graph g;
245 auto nodes = make_nodes(g, 4);
246 // Complete graph K4
247 for (int i = 0; i < 4; ++i)
248 for (int j = i + 1; j < 4; ++j)
249 g.insert_arc(nodes[i], nodes[j], 1);
250
253 alg(nodes[0], cuts);
254
256}
257
259{
260 Graph g;
261 auto nodes = make_nodes(g, 7);
262 /*
263 * 0
264 * / \
265 * 1 2
266 * /| |\
267 * 3 4 5 6
268 */
269 g.insert_arc(nodes[0], nodes[1], 1);
270 g.insert_arc(nodes[0], nodes[2], 1);
271 g.insert_arc(nodes[1], nodes[3], 1);
272 g.insert_arc(nodes[1], nodes[4], 1);
273 g.insert_arc(nodes[2], nodes[5], 1);
274 g.insert_arc(nodes[2], nodes[6], 1);
275
278 alg(nodes[0], cuts);
279
280 EXPECT_EQ(cut_infos(cuts), (std::set<int>{0, 1, 2}));
281}
282
284{
285 Graph g;
286 auto nodes = make_nodes(g, 6);
287 // Two triangles connected by a bridge (nodes[2]--nodes[3])
288 g.insert_arc(nodes[0], nodes[1], 1);
289 g.insert_arc(nodes[1], nodes[2], 1);
290 g.insert_arc(nodes[2], nodes[0], 1);
291 g.insert_arc(nodes[2], nodes[3], 1); // bridge
292 g.insert_arc(nodes[3], nodes[4], 1);
293 g.insert_arc(nodes[4], nodes[5], 1);
294 g.insert_arc(nodes[5], nodes[3], 1);
295
298 alg(nodes[0], cuts);
299
300 EXPECT_EQ(cut_infos(cuts), (std::set<int>{2, 3}));
301}
302
304{
305 Graph g;
306 auto nodes = make_nodes(g, 4);
307 // 4-cycle (biconnected)
308 g.insert_arc(nodes[0], nodes[1], 1);
309 g.insert_arc(nodes[1], nodes[2], 1);
310 g.insert_arc(nodes[2], nodes[3], 1);
311 g.insert_arc(nodes[3], nodes[0], 1);
312
315 alg(nodes[0], cuts);
316
318}
319
321{
322 Graph g;
323 auto nodes = make_nodes(g, 5);
324 // Root connects two separate components
325 g.insert_arc(nodes[0], nodes[1], 1);
326 g.insert_arc(nodes[0], nodes[2], 1);
327 g.insert_arc(nodes[1], nodes[2], 1); // triangle
328 g.insert_arc(nodes[0], nodes[3], 1);
329 g.insert_arc(nodes[3], nodes[4], 1); // separate component
330
333 alg(nodes[0], cuts);
334
337}
338
339// ============================================================================
340// State Machine Tests
341// ============================================================================
342
344{
345 Graph g;
346 auto nodes = make_nodes(g, 3);
347 g.insert_arc(nodes[0], nodes[1], 1);
348
351 alg(nodes[0], cuts);
352
353 Graph sg;
354 EXPECT_THROW(alg.map_subgraph(sg, 1L), std::logic_error);
355}
356
358{
359 Graph g;
360 auto nodes = make_nodes(g, 3);
361 g.insert_arc(nodes[0], nodes[1], 1);
362
365 alg(nodes[0], cuts);
366
367 Graph cg;
369 EXPECT_THROW(alg.map_cut_graph(cg, cross), std::logic_error);
370}
371
373{
374 Graph g;
375 auto nodes = make_nodes(g, 3);
376 g.insert_arc(nodes[0], nodes[1], 1);
377 g.insert_arc(nodes[1], nodes[2], 1);
378
381
382 // Step 1: compute cut nodes
383 alg(nodes[0], cuts);
385
386 // Step 2: paint
387 long num_colors = alg.paint_subgraphs();
389
390 // Step 3: map subgraph (should not throw)
391 Graph sg;
392 EXPECT_NO_THROW(alg.map_subgraph(sg, 1L));
393}
394
396{
397 Graph g;
398 auto nodes = make_nodes(g, 3);
399 g.insert_arc(nodes[0], nodes[1], 1);
400 g.insert_arc(nodes[1], nodes[2], 1);
401
403
405 alg(nodes[0], cuts1);
406 size_t first_count = cuts1.size();
407
409 alg(nodes[0], cuts2);
410
413}
414
415// ============================================================================
416// Operator() Overload Tests
417// ============================================================================
418
420{
421 Graph g;
422 auto nodes = make_nodes(g, 4);
423 g.insert_arc(nodes[0], nodes[1], 1);
424 g.insert_arc(nodes[1], nodes[2], 1);
425 g.insert_arc(nodes[2], nodes[3], 1);
426
429 alg(cuts); // No start node specified
430
431 EXPECT_EQ(cut_infos(cuts), (std::set<int>{1, 2}));
432}
433
435{
436 Graph g;
437 auto nodes = make_nodes(g, 4);
438 g.insert_arc(nodes[0], nodes[1], 1);
439 g.insert_arc(nodes[1], nodes[2], 1);
440 g.insert_arc(nodes[2], nodes[3], 1);
441
444 alg(nodes[3], cuts); // Start from end
445
446 EXPECT_EQ(cut_infos(cuts), (std::set<int>{1, 2}));
447}
448
449// ============================================================================
450// Painting Tests
451// ============================================================================
452
454{
455 Graph g;
456 auto nodes = make_nodes(g, 5);
457 // Star: center is cut node, leaves are separate blocks
458 for (int i = 1; i < 5; ++i)
459 g.insert_arc(nodes[0], nodes[i], 1);
460
463 alg(nodes[0], cuts);
464
465 long num_colors = alg.paint_subgraphs();
467
468 // Center (cut node) should have color 0
470
471 // Each leaf should have a unique color > 0
472 std::set<long> leaf_colors;
473 for (int i = 1; i < 5; ++i)
474 {
475 long c = get_color<Graph>(nodes[i]);
476 EXPECT_GT(c, 0L);
478 }
480}
481
483{
484 Graph g;
485 auto nodes = make_nodes(g, 3);
486 g.insert_arc(nodes[0], nodes[1], 1); // cross arc from cut node 1
487 g.insert_arc(nodes[1], nodes[2], 1); // cross arc from cut node 1
488
491 alg(nodes[0], cuts);
492 alg.paint_subgraphs();
493
494 // All arcs in this path should be cross arcs
495 size_t cross_count = 0;
496 for (auto it = g.get_arc_it(); it.has_curr(); it.next_ne())
497 if (is_a_cross_arc<Graph>(it.get_curr()))
498 ++cross_count;
499
501}
502
504{
505 Graph g;
506 auto nodes = make_nodes(g, 6);
507 // Two triangles with a bridge
508 g.insert_arc(nodes[0], nodes[1], 1);
509 g.insert_arc(nodes[1], nodes[2], 1);
510 g.insert_arc(nodes[2], nodes[0], 1);
511 auto bridge = g.insert_arc(nodes[2], nodes[3], 1);
512 g.insert_arc(nodes[3], nodes[4], 1);
513 g.insert_arc(nodes[4], nodes[5], 1);
514 g.insert_arc(nodes[5], nodes[3], 1);
515
518 alg(nodes[0], cuts);
519 alg.paint_subgraphs();
520
522}
523
525{
526 Graph g;
527 auto nodes = make_nodes(g, 7);
528 // Tree with 4 leaf components
529 g.insert_arc(nodes[0], nodes[1], 1);
530 g.insert_arc(nodes[0], nodes[2], 1);
531 g.insert_arc(nodes[1], nodes[3], 1);
532 g.insert_arc(nodes[1], nodes[4], 1);
533 g.insert_arc(nodes[2], nodes[5], 1);
534 g.insert_arc(nodes[2], nodes[6], 1);
535
538 alg(nodes[0], cuts);
539
540 long num_colors = alg.paint_subgraphs();
541
542 // 4 leaves, each a separate block
543 EXPECT_EQ(num_colors, 5L); // colors 1-4 used, next is 5
544}
545
546// ============================================================================
547// Subgraph Mapping Tests
548// ============================================================================
549
551{
552 Graph g;
553 auto nodes = make_nodes(g, 3);
554 g.insert_arc(nodes[0], nodes[1], 1);
555
558 alg(nodes[0], cuts);
559 alg.paint_subgraphs();
560
561 Graph sg;
562 EXPECT_THROW(alg.map_subgraph(sg, 999L), std::domain_error);
563}
564
566{
567 Graph g;
568 auto nodes = make_nodes(g, 5);
569 for (int i = 1; i < 5; ++i)
570 g.insert_arc(nodes[0], nodes[i], 1);
571
574 alg(nodes[0], cuts);
575 alg.paint_subgraphs();
576
577 // Each leaf is a single-node component
578 for (long color = 1; color <= 4; ++color)
579 {
580 Graph sg;
581 alg.map_subgraph(sg, color);
582
583 EXPECT_EQ(sg.get_num_nodes(), 1U);
584 EXPECT_EQ(sg.get_num_arcs(), 0U);
585 }
586}
587
589{
590 Graph g;
591 auto nodes = make_nodes(g, 3);
592 g.insert_arc(nodes[0], nodes[1], 1);
593 g.insert_arc(nodes[1], nodes[2], 1);
594
597 alg(nodes[0], cuts);
598 alg.paint_subgraphs();
599
600 Graph sg;
601 alg.map_subgraph(sg, 1L);
602
603 // Verify nodes are mapped
604 for (auto it = sg.get_node_it(); it.has_curr(); it.next_ne())
605 {
606 auto sg_node = it.get_curr();
608 EXPECT_NE(orig_node, nullptr);
609 }
610}
611
612// ============================================================================
613// Cut Graph Tests
614// ============================================================================
615
617{
618 Graph g;
619 auto nodes = make_nodes(g, 5);
620 g.insert_arc(nodes[0], nodes[1], 1);
621 g.insert_arc(nodes[1], nodes[2], 1);
622 g.insert_arc(nodes[2], nodes[3], 1);
623 g.insert_arc(nodes[3], nodes[4], 1);
624
627 alg(nodes[0], cuts);
628 alg.paint_subgraphs();
629
630 Graph cg;
632 alg.map_cut_graph(cg, cross);
633
634 EXPECT_EQ(cg.get_num_nodes(), cuts.size());
635}
636
638{
639 Graph g;
640 auto nodes = make_nodes(g, 3);
641 g.insert_arc(nodes[0], nodes[1], 1);
642 g.insert_arc(nodes[1], nodes[2], 1);
643
646 alg(nodes[0], cuts);
647 alg.paint_subgraphs();
648
649 Graph cg;
651 alg.map_cut_graph(cg, cross);
652
653 // Count cross arcs in original graph
654 size_t expected_cross = 0;
655 for (auto it = g.get_arc_it(); it.has_curr(); it.next_ne())
656 if (is_a_cross_arc<Graph>(it.get_curr()))
658
660}
661
662// ============================================================================
663// compute_blocks() Tests
664// ============================================================================
665
667{
668 Graph g;
669 auto nodes = make_nodes(g, 2);
670 g.insert_arc(nodes[0], nodes[1], 1);
671
673
674 DynDlist<Graph> blocks;
675 Graph cg;
677
678 EXPECT_THROW(alg.compute_blocks(blocks, cg, cross), std::logic_error);
679}
680
682{
683 Graph g;
684 auto nodes = make_nodes(g, 5);
685 for (int i = 1; i < 5; ++i)
686 g.insert_arc(nodes[0], nodes[i], 1);
687
690 alg(nodes[0], cuts);
691
692 DynDlist<Graph> blocks;
693 Graph cg;
695
696 // compute_blocks should auto-paint
697 EXPECT_NO_THROW(alg.compute_blocks(blocks, cg, cross));
698 EXPECT_GE(blocks.size(), 4U); // at least 4 leaf blocks (may have empty slots)
699}
700
702{
703 Graph g;
704 auto nodes = make_nodes(g, 7);
705 g.insert_arc(nodes[0], nodes[1], 1);
706 g.insert_arc(nodes[0], nodes[2], 1);
707 g.insert_arc(nodes[1], nodes[3], 1);
708 g.insert_arc(nodes[1], nodes[4], 1);
709 g.insert_arc(nodes[2], nodes[5], 1);
710 g.insert_arc(nodes[2], nodes[6], 1);
711
714 alg(nodes[0], cuts);
715
716 DynDlist<Graph> blocks;
717 Graph cg;
719 alg.compute_blocks(blocks, cg, cross);
720
721 EXPECT_GE(blocks.size(), 4U); // at least 4 leaf components (may have empty slots)
722}
723
725{
726 Graph g;
727 auto nodes = make_nodes(g, 5);
728 g.insert_arc(nodes[0], nodes[1], 1);
729 g.insert_arc(nodes[1], nodes[2], 1);
730 g.insert_arc(nodes[2], nodes[3], 1);
731 g.insert_arc(nodes[3], nodes[4], 1);
732
735 alg(nodes[0], cuts);
736
737 DynDlist<Graph> blocks;
738 Graph cg;
740 alg.compute_blocks(blocks, cg, cross);
741
742 EXPECT_EQ(cg.get_num_nodes(), cuts.size());
743}
744
746{
747 Graph g;
748 auto nodes = make_nodes(g, 3);
749 g.insert_arc(nodes[0], nodes[1], 1);
750 g.insert_arc(nodes[1], nodes[2], 1);
751
754 alg(nodes[0], cuts);
755
756 DynDlist<Graph> blocks;
757 Graph cg;
759 alg.compute_blocks(blocks, cg, cross);
760
762}
763
764// ============================================================================
765// Edge Cases
766// ============================================================================
767
769{
770 Graph g;
771 auto nodes = make_nodes(g, 1);
772
775 alg(nodes[0], cuts);
776
778}
779
781{
782 Graph g;
783 auto nodes = make_nodes(g, 2);
784 g.insert_arc(nodes[0], nodes[1], 1);
785
788 alg(nodes[0], cuts);
789
791}
792
794{
795 Graph g;
796 auto nodes = make_nodes(g, 3);
797 g.insert_arc(nodes[0], nodes[1], 1);
798 g.insert_arc(nodes[1], nodes[2], 1);
799 g.insert_arc(nodes[2], nodes[0], 1);
800
803 alg(nodes[0], cuts);
804
806}
807
809{
810 Graph g;
811 auto nodes = make_nodes(g, 3);
812 g.insert_arc(nodes[0], nodes[1], 1);
813 g.insert_arc(nodes[1], nodes[2], 1);
814 g.insert_arc(nodes[1], nodes[1], 99); // self-loop
815
818 alg(nodes[0], cuts);
819
820 EXPECT_EQ(cut_infos(cuts), (std::set<int>{1}));
821}
822
824{
825 Graph g;
826 auto nodes = make_nodes(g, 3);
827 g.insert_arc(nodes[0], nodes[1], 1);
828 g.insert_arc(nodes[0], nodes[1], 2); // parallel arc
829 g.insert_arc(nodes[1], nodes[2], 1);
830
833 alg(nodes[0], cuts);
834
835 EXPECT_EQ(cut_infos(cuts), (std::set<int>{1}));
836}
837
838// ============================================================================
839// Integration Tests
840// ============================================================================
841
843{
844 Graph g;
845 auto nodes = make_nodes(g, 5);
846 for (int i = 1; i < 5; ++i)
847 g.insert_arc(nodes[0], nodes[i], 1);
848
850
851 // Step 1: Detect cut nodes
853 alg(nodes[0], cuts);
855
856 // Step 2: Paint
857 long num_colors = alg.paint_subgraphs();
859
860 // Step 3: Map all subgraphs
861 for (long color = 1; color < num_colors; ++color)
862 {
863 Graph sg;
864 EXPECT_NO_THROW(alg.map_subgraph(sg, color));
865 }
866
867 // Step 4: Map cut graph
868 Graph cg;
870 EXPECT_NO_THROW(alg.map_cut_graph(cg, cross));
871}
872
874{
875 Graph g;
876 auto nodes = make_nodes(g, 4);
877 g.insert_arc(nodes[0], nodes[1], 1);
878 g.insert_arc(nodes[1], nodes[2], 1);
879 g.insert_arc(nodes[2], nodes[3], 1);
880
882
883 for (int iter = 0; iter < 3; ++iter)
884 {
886 alg(nodes[0], cuts);
887 EXPECT_EQ(cut_infos(cuts), (std::set<int>{1, 2}));
888 }
889}
890
892{
893 Graph g;
894 const int N = 100;
895 auto nodes = make_nodes(g, N);
896
897 // Create a path graph with N-2 cut nodes
898 for (int i = 0; i < N - 1; ++i)
899 g.insert_arc(nodes[i], nodes[i + 1], 1);
900
903 alg(nodes[0], cuts);
904
905 EXPECT_EQ(cuts.size(), static_cast<size_t>(N - 2));
906}
907
909{
910 Graph g;
911 auto nodes = make_nodes(g, 3);
912 g.insert_arc(nodes[0], nodes[1], 1);
913
916 alg(nodes[0], cuts);
917 alg.paint_subgraphs();
918
919 Graph sg;
920 // Attempt with invalid color should throw and clear sg
921 try
922 {
923 alg.map_subgraph(sg, 999L);
924 }
925 catch (const std::domain_error &)
926 {
927 // Graph should be cleared on exception
928 EXPECT_EQ(sg.get_num_nodes(), 0U);
929 EXPECT_EQ(sg.get_num_arcs(), 0U);
930 }
931}
Computation of cut nodes (articulation points) of a graph.
Iterator dynamic list.
Dynamic doubly linked list with O(1) size and bidirectional access.
const size_t & size() const noexcept
Return the number of elements (constant time)
T & insert(const T &item)
Insert a new item by copy.
Definition htlist.H:1502
constexpr bool is_empty() const noexcept
Return true if list is empty.
Definition htlist.H:523
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
Definition tpl_graph.H:524
Arc * insert_arc(Node *src_node, Node *tgt_node, void *a)
Definition tpl_graph.H:604
auto get_arc_it() const noexcept
Obtains an iterator to the arc of graph.
Definition graph-dry.H:2802
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
Definition graph-dry.H:695
constexpr size_t get_num_arcs() const noexcept
Definition graph-dry.H:778
auto get_node_it() const noexcept
Obtains an iterator to the nodes of graph.
Definition graph-dry.H:2780
#define TEST(name)
#define N
Definition fib.C:294
DynArray< Graph::Node * > nodes
Definition graphpic.C:406
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
static long & color(typename GT::Node *p)
DynList< T > maps(const C &c, Op op)
Classic map operation.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
Arc of graph implemented with double-linked adjacency lists.
Definition tpl_graph.H:222
Articulation points (cut nodes) and bridges.
Generic graph and digraph implementations.
Utility algorithms and operations for graphs.