#include #include // Lista simplu inlantuita alocata dinamic // Folosita pentru lista de muchii template class List { private: class Node { public: T data; Node *next; }; Node *m_list, *m_end; public: List():m_list(NULL),m_end(NULL) {} ~List() { release(); } // eleibereaza memorie void release() { Node *c = m_list, *v; while( c ) { v = c; c = c->next; delete v; } } // adauga element la sfarsit void push_back( T data ) { if( !m_list ) { m_list = new Node(); m_list->data = data; m_list->next = NULL; m_end = m_list; return; } Node *c = new Node(); c->data = data; c->next = NULL; m_end->next = c; m_end = c; } // adauga element la inceputul listei void push_first( T data ) { if( !m_list ) { m_list = new Node(); m_list->data = data; m_list->next = NULL; m_end = m_list; return; } Node *c = new Node(); c->data = data; c->next = m_list; m_list = c; } // extrage primul element T pop_first() { T data = m_list->data; Node *c = m_list; m_list = m_list->next; if( !m_list ) m_end = NULL; delete c; return data; } int empty() { if( !m_list ) return 1; return 0; } // iterator pentru parcurgerea listei class iterator { private: Node *m_cursor; public: iterator( Node *p=NULL ):m_cursor(p) {} void operator++(int) { m_cursor = m_cursor->next; } T& operator*() { return m_cursor->data; } int operator!=( iterator i ) { return m_cursor != i.m_cursor; } }; // returneaza iterator de start iterator begin() { return iterator(m_list); } // returneaza iterator final iterator end() { return iterator(NULL); } }; // o muchie din lista // fiecare muchie are un cost asociat class Muchie { public: int v1; int v2; int cost; }; // valoare pentru infinit - de pe info.devnet.ro #define INF 0x3f3f3f3f // graf orientat - stocat prin lista de muchii class Graf { private: List m_muc; int m_nrv, m_nrm; // numar varfuri si numar de muchii // memoreaza costul mediu pana la un punct // bellman ford incearca sa minimizeze acest cost class CostMediu { public: int cost; // costul drumului int lungime; // si lungimea drumului int kmin; // kmin pana la nodul curent inclusiv }; public: // initializare graf Graf( int n = 0 ) { if( !n ) return; create(n); } ~Graf() { release(); } // aloca memorie pentru graf void create( int n ) { // aloca memorie pentru muchii m_nrv = n; m_nrm = 0; } // adauga o muchie in graf void insert( int v1, int v2, int cost ) { if( v1 == v2 ) return; // adauga varful in lista Muchie v; v.v1 = v1; v.v2 = v2; v.cost = cost; m_muc.push_back( v ); m_nrm++; } inline int max( int a, int b ) { if( a>b ) return a; return b; } /// FUNCTIA CEA MAI IMPORTANTA int bellmanford_min_med( int x, int y ) { // bellman ford pentru a minimiza // costul mediu al drumului - raportul dintre lungimea // drumului si costul lui. // vector care retine costul minim al drumului de la varful // x pana la un anumit varf CostMediu *d = new CostMediu[ m_nrv+1 ]; List::iterator it; int i, done = 0; // done este folosit pentru a iesi din bellman ford atunci cand nu mai are loc nici o schimbare double med1, med2; // initializeaza vector de distante // initial costul drumului pana la orice varf este infinit // raportul este tot infinit iar kmin este setat o valoare // negativa care oricum nu exita in graf for( i=1; i<=m_nrv; i++ ) { d[i].cost = INF; d[i].lungime = 1; d[i].kmin = -1; } // initializeaza cost pana varful x d[x].cost = 0; d[x].lungime = 1; // bellman ford for( i=0; i