@@ -100,8 +100,7 @@ class Graph {
100
100
std::vector<Edge> edges{};
101
101
edges.reserve (edges_pairs.size ());
102
102
103
- for (const auto & edge : edges_pairs)
104
- edges.push_back (Edge (edge.first , edge.second ));
103
+ for (const auto & edge : edges_pairs) edges.push_back (edge);
105
104
106
105
return Graph (edges);
107
106
}
@@ -129,8 +128,7 @@ class Graph {
129
128
" match." );
130
129
131
130
for (size_t i = 0 ; i < weights.size (); i++)
132
- edges.push_back (
133
- Edge (edges_pairs[i].first , edges_pairs[i].second , weights[i]));
131
+ edges.push_back (Edge (edges_pairs[i], weights[i]));
134
132
135
133
return Graph (edges);
136
134
}
@@ -294,13 +292,7 @@ class Graph {
294
292
}
295
293
296
294
// / @brief Проверяет, взвешен ли граф
297
- bool IsWeighted () const {
298
- if (edges_.empty ()) return false ;
299
-
300
- bool is_weighted = true ;
301
- for (const auto & edge : edges_) is_weighted &= edge.IsWeighted ();
302
- return is_weighted;
303
- }
295
+ bool IsWeighted () const { return is_weighted_; }
304
296
305
297
// / @return `size_t`: кол-во вершин
306
298
size_t VertsAmount () const { return verts_.size (); }
@@ -367,11 +359,8 @@ class Graph {
367
359
return os;
368
360
}
369
361
370
- /* *
371
- * @brief Делает граф ненаправленным (удаляет лишние ребра)
372
- * @param remove_duplicates: удалять ли дубликаты
373
- */
374
- void MakeUndirected (bool remove_duplicates = false ) {
362
+ // / @brief Делает граф ненаправленным (удаляет лишние ребра)
363
+ void MakeUndirected () {
375
364
std::unordered_set<size_t > seen_edges;
376
365
std::vector<Edge> unique_edges;
377
366
unique_edges.reserve (EdgesAmount ());
@@ -391,8 +380,6 @@ class Graph {
391
380
392
381
edges_ = std::move (unique_edges);
393
382
is_direct_ = false ;
394
-
395
- if (remove_duplicates) RemoveDuplicates ();
396
383
}
397
384
398
385
// / @brief Делает граф направленным (ничего)
@@ -401,19 +388,6 @@ class Graph {
401
388
// / @brief Проверяет, направлен ли граф
402
389
bool IsDirected () const { return is_direct_; }
403
390
404
- // / @brief Удаляет из графа ребрами с одинаковым вершинами
405
- void RemoveDuplicates () {
406
- std::vector<Edge> unique_edges;
407
- unique_edges.reserve (EdgesAmount ());
408
-
409
- for (const auto & edge : edges_)
410
- if (!Contains (unique_edges, edge)) unique_edges.push_back (edge);
411
-
412
- edges_ = std::move (unique_edges);
413
-
414
- if (!IsDirected ()) MakeUndirected ();
415
- }
416
-
417
391
/* *
418
392
* @return `std::vector<std::vector<vert_t>>`: список смежности
419
393
* @throw `std::logic_error("GetAdjListWithoutKeys: this method is deleted
@@ -495,8 +469,6 @@ class Graph {
495
469
* @return `true`: содержится
496
470
* @return `false`: не содержится
497
471
* @throw `std::logic_error("ContainsEdge: graph is not weighted.")`
498
- * @throw `std::logic_error("ContainsEdge: weight must be greater than
499
- * zero.")`
500
472
*/
501
473
bool ContainsEdge (const std::tuple<vert_t , vert_t , weight_t >& edge) const {
502
474
if (!IsWeighted ())
@@ -560,33 +532,22 @@ class Graph {
560
532
if (!Contains (verts_, vert)) verts_.push_back (vert);
561
533
}
562
534
563
- // / @throw `std::invalid_argument(std::string("AddEdge: ") + ex.what())`
564
- void AddEdge (vert_t start_vert, vert_t end_vert, weight_t weight) {
565
- AddVert (start_vert);
566
- AddVert (end_vert);
567
-
568
- try {
569
- edges_.emplace_back (Edge (start_vert, end_vert, weight));
570
- }
571
-
572
- catch (const std::exception& ex) {
573
- throw std::invalid_argument (std::string (" AddEdge: " ) + ex.what ());
574
- }
535
+ // / @warning `"AddEdge: weighted graph must consist of weighted edges.`
536
+ void AddEdge (const std::tuple<vert_t , vert_t , weight_t >& edge_tuple) {
537
+ if (WeightFromTuple (edge_tuple) == 0 )
538
+ AddEdge ({StartVertFromTuple (edge_tuple), EndVertFromTuple (edge_tuple)});
539
+ else
540
+ AddEdge_ (edge_tuple);
575
541
}
576
542
577
- /* *
578
- * @throw `std::logic_error("AddEdge: weighted graph must consist of
579
- * weighted edges.")`
580
- */
581
- void AddEdge (vert_t start_vert, vert_t end_vert) {
543
+ // / @warning `"AddEdge: weighted graph must consist of weighted edges.`
544
+ void AddEdge (const std::pair<vert_t , vert_t >& edge_pair) {
582
545
if (IsWeighted ())
583
- throw std::logic_error (
584
- " AddEdge: weighted graph must consist of weighted edges." );
546
+ std::cerr << " Warning! AddEdge: weighted graph should consist of "
547
+ " weighted edges."
548
+ << std::endl;
585
549
586
- AddVert (start_vert);
587
- AddVert (end_vert);
588
-
589
- edges_.emplace_back (Edge (start_vert, end_vert));
550
+ AddEdge_ (Edge (edge_pair.first , edge_pair.second , static_cast <weight_t >(0 )));
590
551
}
591
552
592
553
// / @throw `std::invalid_argument("RemoveVert: there is no such vert:")`
@@ -622,8 +583,7 @@ class Graph {
622
583
623
584
edges_.erase (std::remove_if (edges_.begin (), edges_.end (),
624
585
[&edge_pair, this ](const Edge& e) {
625
- return (Edge (e.StartVert (), e.EndVert ()) ==
626
- Edge (edge_pair)) ||
586
+ return (e == Edge (edge_pair)) ||
627
587
(!IsDirected () &&
628
588
Edge (e.EndVert (), e.StartVert ()) ==
629
589
Edge (edge_pair));
@@ -656,16 +616,21 @@ class Graph {
656
616
public:
657
617
Edge () = delete ;
658
618
659
- Edge (vert_t start_vert, vert_t end_vert)
619
+ Edge (const vert_t start_vert, const vert_t & end_vert)
660
620
: start_vert_{start_vert}, end_vert_{end_vert} {}
661
621
662
- Edge (vert_t start_vert, vert_t end_vert, weight_t weight)
622
+ Edge (const vert_t & start_vert, vert_t end_vert, weight_t weight)
663
623
: start_vert_{start_vert}, end_vert_{end_vert}, weight_{weight} {}
664
624
665
- Edge (std::pair<vert_t , vert_t > edge_pair)
625
+ Edge (const std::pair<vert_t , vert_t >& edge_pair)
666
626
: start_vert_{edge_pair.first }, end_vert_{edge_pair.second } {}
667
627
668
- Edge (std::tuple<vert_t , vert_t , weight_t > edge_tuple)
628
+ Edge (const std::pair<vert_t , vert_t >& edge_pair, weight_t weight)
629
+ : start_vert_{edge_pair.first },
630
+ end_vert_{edge_pair.second },
631
+ weight_{weight} {}
632
+
633
+ Edge (const std::tuple<vert_t , vert_t , weight_t >& edge_tuple)
669
634
: start_vert_{StartVertFromTuple (edge_tuple)},
670
635
end_vert_{EndVertFromTuple (edge_tuple)},
671
636
weight_{WeightFromTuple (edge_tuple)} {}
@@ -679,11 +644,13 @@ class Graph {
679
644
680
645
void SetWeight (weight_t new_weight) { weight_ = new_weight; }
681
646
682
- // friend Graph;
683
-
684
647
bool operator ==(const Edge& rhs) const {
685
- return start_vert_ == rhs.start_vert_ && end_vert_ == rhs.end_vert_ &&
686
- weight_ == rhs.weight_ ;
648
+ if (StartVert () != rhs.StartVert () || EndVert () != rhs.EndVert ())
649
+ return false ;
650
+
651
+ if (IsWeighted () && rhs.IsWeighted ()) return Weight () == rhs.Weight ();
652
+
653
+ return true ;
687
654
}
688
655
689
656
bool operator !=(const Edge& rhs) const { return !(*this == rhs); }
@@ -727,6 +694,7 @@ class Graph {
727
694
std::vector<vert_t > verts_;
728
695
729
696
bool is_direct_ = true ;
697
+ bool is_weighted_ = false ;
730
698
731
699
public:
732
700
friend std::ostream& operator <<(std::ostream& os,
@@ -736,9 +704,14 @@ class Graph {
736
704
}
737
705
738
706
private:
739
- Graph (const std::vector<Edge>& edges) : edges_{edges}, verts_() {
707
+ Graph (const std::vector<Edge>& edges) {
740
708
if (edges.empty ()) return ;
741
709
710
+ for (const auto & edge : edges) {
711
+ if (edge.IsWeighted ()) is_weighted_ = true ;
712
+ AddEdge_ (edge);
713
+ }
714
+
742
715
if constexpr (std::is_integral_v<vert_t >) {
743
716
// кол-во вершин = максимальная вершина среди ребер, т.е. в этом случае
744
717
// происходит заполнение вершин до наибольшей из них в списке ребер
@@ -752,17 +725,23 @@ class Graph {
752
725
verts_.resize (max_vert + 1 );
753
726
std::iota (verts_.begin (), verts_.end (), 0 );
754
727
755
- } else if constexpr (std::is_same_v<vert_t , std::string>) {
728
+ } else if constexpr (std::is_same_v<vert_t , std::string>)
756
729
for (const auto & edge : edges_) {
757
730
if (!Contains (Verts (), edge.StartVert ()))
758
731
verts_.push_back (edge.StartVert ());
759
732
760
733
if (!Contains (Verts (), edge.EndVert ()))
761
734
verts_.push_back (edge.EndVert ());
762
735
}
763
- }
736
+ }
737
+
738
+ void AddEdge_ (const Edge& edge) {
739
+ AddVert (edge.StartVert ());
740
+ AddVert (edge.EndVert ());
741
+
742
+ if (!Contains (edges_, edge)) edges_.emplace_back (edge);
764
743
765
- if (! IsDirected ()) MakeUndirected () ;
744
+ if (edge. Weight () != 0 ) is_weighted_ = true ;
766
745
}
767
746
768
747
static std::pair<vert_t , vert_t > ParseEdgeString_ (
0 commit comments