#include #include #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 Edge { public: int dest; int weight; }; typedef std::vector Edge_vector_type; class Vertex { public: Edge_vector_type Adj; int id; int distance; Vertex* predecessor; void PrintVertex(int print_adj); void Relax(Vertex*); Vertex(int i, int dist, Vertex* pred); }; void Vertex::PrintVertex(int print_adj) { cout << "ID: " << id << " d: " << distance << " p: "; if (predecessor) cout << predecessor->id; else cout << "NONE"; if (print_adj) { cout << endl << "Adj: "; for (int i=0; i < Adj.size(); i++) cout << Adj.at(i).dest << " "; } cout << endl; } Vertex::Vertex (int i, int dist, Vertex* pred) { Edge e; id = i; distance = dist; predecessor = pred; for (int c=0; c < VCOUNT; c++) if (AM[id][c]) { e.weight = AM[id][c]; e.dest = c; Adj.push_back(e); } } int edge_weight(Vertex source, Vertex destination) { if (AM[source.id][destination.id]) return AM[source.id][destination.id]; else return -1; } void Vertex::Relax(Vertex* v) { int ew; ew = edge_weight(*v, *this); if ((distance > ew + v->distance) || (distance == -1)){ distance = ew + v->distance; predecessor = v; } } typedef std::vector Graph_Type; void Print_Graph(Graph_Type g, int print_adj) { for (int i=0; i < g.size(); i++) g.at(i)->PrintVertex(print_adj); } 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 Clean_Up(Graph_Type g) { for (int i=0; i < g.size(); i++) { delete g.at(i); g.at(i) = NULL; } } Vertex* Extract_Min(Graph_Type* q) { // assumes q is non-empty Vertex* t; int smallest, i; std::vector::iterator ip; smallest = 0; for (i=1; i < q->size(); i++) { if ((q->at(i)->distance < q->at(smallest)->distance) && (q->at(i)->distance != -1)) smallest = i; } t = q->at(smallest); ip = q->begin(); ip += smallest; q->erase(ip); return t; } Vertex* Find_Vertex(Graph_Type* g, int v_id) { for(int i=0; i < g->size(); i++) if (g->at(i)->id == v_id) return g->at(i); return NULL; } Graph_Type Dijkstra(Graph_Type* q, int v_id) { Graph_Type s; Vertex* u; Vertex* v; int i; q->at(v_id)->distance = 0; while (q->size() > 0) { u = Extract_Min(q); s.push_back(u); for (i=0; i < u->Adj.size(); i++) { v = Find_Vertex(q, u->Adj.at(i).dest); if (v) v->Relax(u); } } return s; } 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 graph" << endl; Print_Graph(s, 0); Clean_Up(s); }