#include <iostream> #include <map> #include <functional> #include <initializer_list>
enum:int{ MAXVALUE = 999 }; //匿名枚举类型.
template<typename T> struct Edge{ T startNode; T endNode; Edge()=default; template<typename Ty> Edge(const Ty& startNode_, const Ty& endNode_); };
template<typename T> template<typename Ty> Edge<T>::Edge(const Ty& startNode_, const Ty& endNode_) :startNode(startNode_), endNode(endNode_) { // }
template<typename T> class Graph{ private: std::map<T, std::map<T, int>> edges; //存储边. std::map<T, int> vertices; //存储顶点. Edge<T>* edgeArray; bool flag; int nodeNumber; int edgeNumber; template<typename Ty> void initialize_single_source(const Ty& source_)noexcept; template<typename Ty> void relax(const Ty& source_)noexcept; public: template<typename Ty, unsigned int N> Graph(const std::initializer_list<Ty>& vertices_, const Ty (&edges_)[N][3]); ~Graph(); template<typename Ty> void Bellman_ford(const Ty& source_); template<typename Ty> void printPath(const Ty& source_)const; };
template<typename T> template<typename Ty, unsigned int N> Graph<T>::Graph(const std::initializer_list<Ty>& vertices_, const Ty (&edges_)[N][3]) :flag(false) { if(N == 0 || vertices_.size() == 0){ throw std::runtime_error("it is empty in the graph"); } this->nodeNumber = vertices_.size(); this->edgeNumber = N; this->edgeArray = new Edge<Ty>[N]; //存储各个边的结点值. typename std::initializer_list<Ty>::iterator it = vertices_.begin(); for(; it != vertices_.end(); ++it){ this->vertices[*it] = MAXVALUE; } for(int i=0; i<N; ++i){ Edge<Ty> edge(edges_[i][0], edges_[i][1]); this->edges[edges_[i][0]][edges_[i][1]] = edges_[i][2]; this->edgeArray[i]=edge; } std::cout<<"out of constructor"<<std::endl; }
template<typename T> template<typename Ty> void Graph<T>::initialize_single_source(const Ty& source_)noexcept { this->vertices[source_] = 0; //make the source node'degree of the graph 0; others is MAXVALUE. }
template<typename T> template<typename Ty> void Graph<T>::relax(const Ty& source_)noexcept //noexcept show that the function can not throw exception; { for(int i=1; i<this->nodeNumber; ++i){ for(int j=0; j<this->edgeNumber; ++j){ if(this->vertices[source_] != MAXVALUE){ if(this->vertices[this->edgeArray[j].endNode] > this->vertices[this->edgeArray[j].startNode] + this->edges[this->edgeArray[j].startNode][this->edgeArray[j].endNode]){ this->vertices[this->edgeArray[j].endNode] = this->vertices[this->edgeArray[j].startNode] + this->edges[this->edgeArray[j].startNode][this->edgeArray[j].endNode]; //这两行写的比较长=.= //其中this->vertices[this->edgeArray[j].startNode]获得的是该边的顶结点的distance(注:distance是指的是从当前顶点到source_这个给定顶点的距离). //this->vertices[this->edgeArray[j].endNode]获得的是改变尾结点的distance. } } } } }
template<typename T> template<typename Ty> void Graph<T>::Bellman_ford(const Ty& source_) { this->initialize_single_source(source_); this->relax(source_); for(int i=0; i<this->edgeNumber; ++i){ if(this->vertices[this->edgeArray[i].endNode] > this->vertices[this->edgeArray[i].startNode] + this->edges[this->edgeArray[i].startNode][this->edgeArray[i].endNode]){ this->flag = false; break; } } this->flag = true; this->printPath(source_); }
template<typename T> Graph<T>::~Graph() { if( !this->edges.empty() ){ this->edges.clear(); } if( !this->vertices.empty() ){ this->vertices.clear(); } if(this->edgeArray != nullptr){ delete[] edgeArray; this->edgeArray = nullptr; } }
template<typename T> template<typename Ty> void Graph<T>::printPath(const Ty& source_)const { if( this->flag == false ){ std::cout<<"there is not the shortest way."<<std::endl; }else{ typename std::map<Ty, int>::const_iterator it = this->vertices.cbegin(); for(int i=0; i<this->nodeNumber; ++i){ std::cout<<source_<<" "<<it->first<<" "<<it->second<<std::endl; } } }
int main() { int edges_[][3]={{0,1, 5}, {0,2, 8}, {0,3, -4}, {1,0, -2}, {2,1, -3}, {2,3, 9}, {3,1, 7}, {3,4, 2}, {4,0, 6}, {4,2, 7}}; Graph<int> myGraph({0, 1, 2, 3, 4}, edges_); myGraph.Bellman_ford(3); return 0; }