#include <iostream> #include <stdexcept> #include <vector> #include <algorithm> #include <memory> #include <map>
namespace{ enum:int{ MAXVALUE = 9999 }; }
template<typename T> class Node{ private: T key_; public: typedef T key_type; //构造函数. template<typename Ty> Node(const Ty& key); //拷贝构造函数. template<typename Ty> Node(const Node<Ty>& otherNode_); //移动构造函数. template<typename Ty> Node(Node<Ty>&& otherNode_); //默认构造函数. Node() = default; //析构函数. ~Node(); template<typename Ty> Node<Ty>& operator*()const; //==函数. template<typename Ty> friend bool operator==(const Node<Ty>& first_, const Node<Ty>& second_); //<函数. template<typename Ty> friend bool operator<(const Node<Ty>& first_, const Node<Ty>& second_); //拷贝赋值运算符. const Node<T>& operator=(const Node<T>& otherNode_);//必须这么写 不然编译器还会合成. //<<函数. template<typename Ty> friend std::ostream& operator<<(std::ostream& os, const Node<Ty>& node_); //移动赋值运算符. template<typename Ty> void operator=(Node<Ty>&& otherNode_); };
template<typename T> template<typename Ty> Node<T>::Node(const Ty& key) :key_(key) { //std::cout<<"constructor function."<<std::endl; }
template<typename T> template<typename Ty> Node<T>::Node(const Node<Ty>& otherNode_) :key_(otherNode_.key_) { std::cout<<"copy for constructor"<<std::endl; }
template<typename T> Node<T>::~Node() { // }
template<typename Ty> bool operator==(const Node<Ty>& first_, const Node<Ty>& second_) { return (first_.key_ == second_.key_) ? true : false; }
template<typename T> const Node<T>& Node<T>::operator=(const Node<T>& otherNode_) //必须这么写不然编译器自己合成. { this->key_ = otherNode_.key_; std::cout<<"copy function"<<std::endl; }
template<typename T> template<typename Ty> Node<Ty>& Node<T>::operator*()const { return *this; }
template<typename Ty> bool operator<(const Node<Ty>& first_, const Node<Ty>& second_) { //std::cout<<"<"<<std::endl; return (first_.key_ < second_.key_) ? true : false; }
template<typename Ty> std::ostream& operator<<(std::ostream& os, const Node<Ty>& node_) { os<<node_.key_<<std::endl; return os; }
template<typename T> template<typename Ty> void Node<T>::operator=(Node<Ty>&& otherNode_) { std::cout<<"operator move"<<std::endl; this->key_ = otherNode_.key_; }
template<typename T> class Map{ private: //class in class. class Compare{ public: template<typename Ty> bool operator()(const Node<Ty>& first_, const Node<Ty>& second_); }; //class in class. class Container{ public: template<typename Ty> bool operator()(Map<Ty>* temp_map, typename Map<Ty>::cv_iter currentIter_first, typename Map<Ty>::v_iter currentIter_second); }; std::map<Node<T>, std::map<Node<T>, int>> graph_; //该边的加权值可以为负 static std::map<Node<T>, std::vector<Node<T>>> adjList_; std::map<Node<T>, std::map<Node<T>, int>> temp_graph_; unsigned int nodeNumber_; typename Map<T>::Graph extend_shortest_paths(); const int& min(const int& first_, const int& second_); public: typedef std::map<Node<T>, std::map<Node<T>, int>> Graph; using v_iter = typename std::vector<Node<T>>::const_iterator;//类型别名. using cv_iter = typename std::map<Node<T>, std::vector<Node<T>>>::const_iterator; template<typename Ty> using cmm_iter = typename std::map<Node<Ty>, std::map<Node<Ty>, int>>::const_iterator;//类型别名. template<typename Ty> using cm_iter = typename std::map<Node<Ty>, int>::const_iterator; template<typename Ty, unsigned int N> Map(const Ty (&edge)[N][3]); ~Map(); Map()=default; void slow_all_pairs_shortest_paths(); void print(); };
template<typename T> std::map<Node<T>, std::vector<Node<T>>> Map<T>::adjList_;
template<typename T> template<typename Ty, unsigned int N> Map<T>::Map(const Ty (&edges)[N][3]) :nodeNumber_(N) { if(N == 0){ throw std::runtime_error(std::string("there is nothing in graph")); } for(int i =0; i<N; ++i){ //存储无向图中的数据以及两个相连接结点之前的加权值。 Node<Ty> first_(edges[i][0]); Node<Ty> second_(edges[i][2]); this->graph_[first_][second_] = edges[i][1]; //this->temp_graph_[first_][second_] = ::MAXVALUE; this->adjList_[first_].push_back(second_); //邻接链表:跟结点A相连接的所有结点都被放在一个vector中. //std::cout<<"first: "<<first_<<std::endl; //std::cout<<"second: "<<second_<<std::endl; } cv_iter iter_first = this->adjList_.cbegin(); for(; iter_first != this->adjList_.cend(); ++iter_first){ v_iter iter_second = this->adjList_[iter_first->first].cbegin(); for(; iter_second != this->adjList_[iter_first->first].cend(); ++iter_second){ std::cout<<"iter_first: "<<iter_first->first<<std::endl; std::cout<<"iter_second: "<<*iter_second<<std::endl; } } }
template<typename T> typename Map<T>::Graph Map<T>::extend_shortest_paths() { Container jundge_; cv_iter first_ = this->adjList_.cbegin(); Graph l_graph_; for(; first_ != this->adjList_.cend(); ++first_){ //std::cout<<"first_->first"<<first_->first<<std::endl; v_iter second_ = this->adjList_[first_->first].cbegin(); for(; second_ != this->adjList_[first_->first].cend(); ++second_){ //std::cout<<"second_: "<< *second_ <<std::endl; l_graph_[first_->first][*second_] = ::MAXVALUE; cv_iter third_ = this->adjList_.cbegin(); for(; third_ != this->adjList_.cend(); ++third_){ bool boolean = jundge_(this, third_, second_); if(boolean == false){ continue; } std::cout<<"first_:"<<(first_->first)<<std::endl; std::cout<<"second_: "<<*second_<<std::endl; std::cout<<"third_: "<<third_->first<<std::endl; l_graph_[first_->first][*second_] = this->min(l_graph_[first_->first][*second_], this->temp_graph_[first_->first][third_->first]+this->graph_[third_->first][*second_]); } } } return l_graph_; }
template<typename T> void Map<T>::slow_all_pairs_shortest_paths() { for(int i=1; i<this->nodeNumber_; ++i){ this->temp_graph_ = this->extend_shortest_paths(); } }
template<typename T> template<typename Ty> bool Map<T>::Compare::operator()(const Node<Ty>& first_, const Node<Ty>& second_) { return first_ < second_ ? true : false; }
template<typename T> const int& Map<T>::min(const int& first_, const int& second_) { return (first_ < second_) ? first_ : second_; }
template<typename T> template<typename Ty> bool Map<T>::Container::operator()(Map<Ty>* temp_map, typename Map<Ty>::cv_iter currentIter_first, typename Map<Ty>::v_iter currentIter_second) { if(temp_map->adjList_[currentIter_first->first].empty()){ return false; }else{ typename Map<Ty>::v_iter first_ = temp_map->adjList_[currentIter_first->first].cbegin(); typename Map<Ty>::v_iter second_ = temp_map->adjList_[currentIter_first->first].cend(); typename Map<Ty>::v_iter third_; third_=std::find_if(first_, second_, [currentIter_second](const Node<Ty>& temp_)->bool { return (temp_ == *currentIter_second) ? true : false; }); if(third_ == second_){ return false; }else{ return true; } } }
template<typename T> void Map<T>::print() { if(this->temp_graph_.empty()){ std::cout<<"there is nothing/n"<<std::endl; return; }else{ cmm_iter<T> begin = this->temp_graph_.cbegin(); for(; begin != this->temp_graph_.cend(); ++begin){ Node<T> temp_node = begin->first; cm_iter<T> begin_ = this->temp_graph_[temp_node].cbegin(); for(; begin_ != this->temp_graph_[temp_node].cend(); ++begin_){ std::cout<< (begin->first) <<"<->"<<begin_->second<<"<->"<<begin_->first<<std::endl; } } } }
template<typename T> Map<T>::~Map() { if(!this->graph_.empty()){ this->graph_.clear(); } if(!this->adjList_.empty()){ this->adjList_.clear(); } if(!this->temp_graph_.empty()){ this->temp_graph_.clear(); } }
int main() { /*Node<int> one_(20); Node<int> two_(30); Node<int> three_; three_ = one_; one_ = two_; std::cout<<one_; three_ = std::move(one_); std::cout<<std::boolalpha<< (one_<two_ )<<std::endl;*/ int graph[9][3]={ {1, 3, 2},//node--weighting--node. {1, 8, 3}, {1, -4, 5}, {2, 7, 5}, {2, 1, 4}, {3, 4, 2}, {4, 2, 1}, {4, -5, 3}, {5, 6, 4} }; Map<int> myGraph(graph); myGraph.slow_all_pairs_shortest_paths(); myGraph.print(); return 0; }