Úloha 4.3
Napíšte program, zdrojový kód, v jazyku C++ použitím štandardu C++17, ktorý realizuje nasledovnú činnosť.
Implementujte graf, ktorého hrany majú definovanú váhu, t.j. ováhovaný graf. Uzol grafu má označenie ‘label’ typu
string. Hrana spájajúca dva uzly musí mať definovanú váhu typu int. Hrany medzi uzlami nemajú orientáciu a tak
prechádzanie medzi uzlami môže byť oboma smermi.
Pre graf implementujte nasledovné metódy:
bool add_vertex(Vertex*, int*)- Pridanie nového uzla do grafu. Metóda má byť ako public člen triedy Vertex. Prvý argument je pointer na uzol s ktorým chceme prepojenie vytvoriť. Druhý argument je váha hrany, ktorá bude vytvorená medzi týmito dvomi uzlami.int count(vector<string>*)- Ak váha hrany predstavuje cenu, ktorú treba zaplatiť aby sme prešli po danej hrane na ďalší uzol, tak táto metóda vráti celkovú cenu cesty z uzla na uzol. Argument metódy je cesta prechádzania uzlov, kde prvok vektora je označenie (label) uzla. Ak taká cesta v grafe existuje metóda vráti jej celkovú cenu. Ak cesta neexistuje, t.j. neexistuje hrana, ktorá by prepojila dva uzly, ktoré sú za sebou definové vo vstupnom vektore, metóda vráti hodnotu-1.
Príklady vstupov / výstupov programu
Ak máme graf s nasledujúcou štruktúrou:

Volanie funkcie pre výpočet celkovej ceny cesty (celkovej váhy) má nasledovné výsledky:
count({1,4,3}) == 8;
count({2,5,1,4}) == 14;
count({3,1,2,5,1}) == 18;Rozbaľ pre ukážku riešenia
Ováhovaný neorientovaný graf implementovaný pomocou triedy Vertex. Každý vrchol uchováva informácie o svojich susedoch a váhach hrán.
#include <iostream>
#include <unordered_map>
#include <vector>
#include <string>
using namespace std;
class Vertex {
private:
string label;
unordered_map<string, pair<Vertex*, int>> neighbors; // mapa: label suseda -> (pointer, váha)
public:
// Konštruktor
explicit Vertex(const string& lbl) : label(lbl) {}
// Getter pre label
string get_label() const {
return label;
}
// Pridanie hrany medzi this a druhým uzlom
bool add_vertex(Vertex* other, int* weight_ptr) {
if (!other || !weight_ptr) return false;
const string& other_label = other->get_label();
// Ak už je hrana medzi týmito uzlami, nepridávaj znova
if (neighbors.find(other_label) != neighbors.end()) {
return false;
}
// Pridaj hranu do oboch strán (graf je neorientovaný)
neighbors[other_label] = make_pair(other, *weight_ptr);
other->neighbors[label] = make_pair(this, *weight_ptr);
return true;
}
// Spočítanie ceny cesty podľa zoznamu labelov
int count(vector<string>* path) {
if (!path || path->empty()) return -1;
int total_cost = 0;
Vertex* current = this;
for (size_t i = 1; i < path->size(); ++i) {
const string& next_label = (*path)[i];
auto it = current->neighbors.find(next_label);
if (it == current->neighbors.end()) {
return -1; // neexistuje hrana medzi current a next_label
}
total_cost += it->second.second; // pripočítaj váhu hrany
current = it->second.first; // posuň sa na ďalší uzol
}
return total_cost;
}
};
int main() {
// Vytvorenie vrcholov
Vertex a("A");
Vertex b("B");
Vertex c("C");
Vertex d("D");
// Vytvorenie hrán s váhami
int ab = 5;
int ac = 3;
int bc = 2;
int cd = 4;
a.add_vertex(&b, &ab);
a.add_vertex(&c, &ac);
b.add_vertex(&c, &bc);
c.add_vertex(&d, &cd);
// Cesta: A -> C -> D
vector<string> path1 = {"A", "C", "D"};
cout << "Cost A->C->D: " << a.count(&path1) << endl; // očakávané: 3 + 4 = 7
// Cesta: A -> B -> C -> D
vector<string> path2 = {"A", "B", "C", "D"};
cout << "Cost A->B->C->D: " << a.count(&path2) << endl; // očakávané: 5 + 2 + 4 = 11
// Neexistujúca cesta: A -> D
vector<string> path3 = {"A", "D"};
cout << "Cost A->D: " << a.count(&path3) << endl; // očakávané: -1
return 0;
}Vysvetlenie
- Každý
Vertexobsahuje mapu svojich susedov (unordered_map<string, pair<Vertex*, int>>), kde:stringjelabelsuseda,Vertex*je pointer na suseda,intje váha hrany.
- Metóda
add_vertex()zabezpečuje pridanie obojstrannej hrany (graf je neorientovaný). - Metóda
count()počíta cenu cesty cez daný zoznam názvov uzlov – ak niektorá hrana chýba, vráti-1.
Ukážkový výstup
Cost A->C->D: 7
Cost A->B->C->D: 11
Cost A->D: -1ASCII vizualizácia
[A]
/ \
5 / \ 3
/ \
[B]--2--[C]--4--[D]