#include #include using namespace std; #define VCOUNT 5 int AM[VCOUNT][VCOUNT] = { 0, 10, 0, 5, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 4, 0, 3, 9, 0, 2, 7, 0, 6, 0, 0}; class Vertex; class Edge { public: int weight; int v; protected: private: }; typedef std::vector Edge_vector_type; class Vertex { public: int id; int distance; Vertex* predecessor; Edge_vector_type Adj; void Relax(Vertex*); Vertex(int i, int dist, Vertex* pred); void PrintVertex(int show_adj); protected: private: }; typedef std::vector Graph_type; int edge_weight(Vertex u, Vertex v) { if (AM[u.id][v.id] > 0) return AM[u.id][v.id]; else return -1; // not found } void Vertex::PrintVertex(int show_adj) { cout << "ID:" << id << " d:" << distance << " p:"; if (predecessor) cout << predecessor->id; else cout << "NONE"; if (show_adj) { cout << endl << "adj: "; for (int i=0; i < Adj.size(); i++) cout << Adj.at(i).v << " "; } cout << endl; } Vertex::Vertex(int i, int dist, Vertex* pred) { Edge u; id = i; distance = dist; predecessor = pred; for (int c=0; c < VCOUNT; c++) { if (AM[id][c] > 0) { u.v = c; u.weight = AM[id][c]; Adj.push_back(u); } } } void Vertex::Relax(Vertex* v) { int ew; ew = edge_weight (*v, *this); if ((distance > v->distance + ew) || (distance == -1)) { distance = v->distance + ew; predecessor = v; } } void clean_up (Graph_type g) { for (int i; i < g.size(); i++) delete g.at(i); } void print_graph(Graph_type g, int show_adj) { for (int i=0; i < g.size(); i++) g.at(i)->PrintVertex(show_adj); } Vertex* ExtractSmallest(Graph_type* g) { // presumes a non empty graph Vertex* t; int i, smallest; std::vector::iterator ip; smallest = 0; for (i=0; i < g->size(); i++) { if ((g->at(i)->distance < g->at(smallest)->distance) && (g->at(i)->distance >= 0)) smallest = i; } t = g->at(smallest); ip = g->begin(); ip += smallest; g->erase(ip); return t; } void SetInfo(Graph_type* g, int v_id, int d, Vertex* p) { for (int i=0; i < g->size(); i++) if (g->at(i)->id == v_id) { g->at(i)->distance = d; g->at(i)->predecessor = p; break; } } Vertex* FindVertex(Graph_type* g, int v_id) { int i; for (i=0; i < g->size(); i++) if (g->at(i)->id == v_id) return g->at(i); return NULL; } Graph_type Dijkstra(Graph_type* g, int v_id) { Graph_type s; Vertex* tu; Vertex* tv; SetInfo(g, v_id, 0, NULL); while (g->size() > 0) { tu = ExtractSmallest(g); s.push_back(tu); for (int i=0; i < tu->Adj.size(); i++) { tv = FindVertex(g, tu->Adj.at(i).v); if (tv) tv->Relax(tu); } } return s; } void create_graph(Graph_type* g) { Vertex* v; for (int i=0; i < VCOUNT; i++) { v = new Vertex(i, -1, NULL); g->push_back(v); } } void main (void) { Graph_type G, S; create_graph(&G); cout << "Original graph" << endl; print_graph(G, 1); S = Dijkstra(&G, 0); cout << endl << "Resultant Dijkstra tree" << endl; print_graph(S, 0); clean_up(G); }