floyd_warshall 算法.

#include <iostream>
#include <map>
#include <memory>
#include <new>
#include <stdexcept>
namespace{
 enum : int{
  MAXVALUE = 9999
 };
}
template<typename T>
class Graph{
 private:
  std::map<T, std::map<T, int>> graph_; //存储有向图. 
  std::map<T, std::map<T, T>> path_; //存储图中两个结点间的中间结点. 
  std::map<T, std::map<T, int>> distance_; //存储两个结点间的距离. 
  
  unsigned int node_number_;
  
  void floyd_warshall()noexcept;
  
  template<typename Ty>
  void print_path(const Ty& start_, const Ty& end_);
  
  public:
   using map_type = std::map<T, std::map<T, int>>;
   
   using map_iter = typename std::map<T, std::map<T, int>>::const_iterator;
   
   using iter = typename std::map<T, int>::const_iterator;
   
   template<typename Ty, unsigned int N>
   Graph(const Ty (&edges)[N][3]);
   
   ~Graph();
   
   template<typename Ty>
   void print(const Ty& start, const Ty& end);
};
template<typename T>
template<typename Ty, unsigned int N>
Graph<T>::Graph(const Ty (&edges)[N][3])
         :node_number_(N)
{
 if(N == 0){
  throw std::runtime_error(std::string("there is nothing"));
 }
 
 /*for(int i=0; i<N; ++i){
  for(int j=0; j<N; ++j){
   (this->*graph_)[i][j] = (i == j) ? 0 : ::MAXVALUE; //如果该点的距离为从自身到自身那么距离为0. 
  }
 }*/
 
 for(int j =0; j<N; ++j){
  (this->graph_)[edges[j][0]][edges[j][1]] = edges[j][2];
 }
 
 map_iter first_ = (this->graph_).cbegin();
 for(; first_ != (this->graph_).cend(); ++first_){
  
  map_iter second_ = (this->graph_).cbegin();
  for(; second_ != (this->graph_).cend(); ++second_){
   
   if(first_->first == second_->first){
    (this->graph_)[first_->first][second_->first] = 0;
    
   }else if((this->graph_)[first_->first][second_->first] > 0){
    continue;
    
   }else{
    (this->graph_)[first_->first][second_->first] = ::MAXVALUE;
   }
  }
 }
 
 std::cout<<"successful constructor\n";
 
 /*map_iter iter_first = this->graph_.cbegin();
 for(; iter_first != this->graph_.cend(); ++iter_first){
  
  std::cout<<iter_first->first<<":  ";
  iter iter_second = this->graph_[iter_first->first].cbegin();
  for(; iter_second != this->graph_[iter_first->first].cend(); ++iter_second){
   
   std::cout<<iter_second->first<<"--"<<iter_second->second<<"  ";
  }
  
  std::cout<<std::endl;
 }*/
}
template<typename T>
void Graph<T>::floyd_warshall()noexcept
{
 if(this->node_number_ == 0){
  throw std::runtime_error(std::string("there nothing in graph"));
 }
 
 //注意下面的双重循环:
 //first_, second_, 以first_为起点second_为终点不断的查找这两个结点间的距离. 
 map_iter first_ = (this->graph_).cbegin();
 for(; first_ != (this->graph_).cend(); ++first_){
  
  map_iter second_ = (this->graph_).cbegin();
  for(; second_ != (this->graph_).cend(); ++second_){
   
   //std::cout<<"dis_: "<<(this->graph_)[first_->first][second_->first]<<std::endl;
   this->distance_[first_->first][second_->first] = (this->graph_)[first_->first][second_->first];  
   this->path_[first_->first][second_->first] = 0;
  }
 }
 
 /*std::cout<<'\n'<<"distance_"<<std::endl;
 map_iter x = this->distance_.cbegin();
 for(; x != this->distance_.cend(); ++x){
  
  std::cout<<x->first<<":  ";
  iter y = (this->distance_)[x->first].cbegin();
  for(; y != (this->distance_)[x->first].cend(); ++y){
   
   std::cout<<y->first<<"--"<<y->second<<"  ";
  }
  std::cout<<std::endl;
 }*/
 
 
 //假设third_为从forth_到fifth_的中间结点. 来不断的寻找两个结点间的最短路径. 
 map_iter third_ = (this->graph_).cbegin();
 
 for(; third_ != (this->graph_).cend(); ++third_){
  
  map_iter forth_ = (this->graph_).cbegin(); 
  for(; forth_ != (this->graph_).cend(); ++forth_){
   
   map_iter fifth_ = (this->graph_).cbegin();
   for(; fifth_ != (this->graph_).cend(); ++fifth_){
    
    /*std::cout<<"i-k:"<<(this->distance_)[forth_->first][third_->first]<<"  ";
    std::cout<<"k-j:"<<(this->distance_)[third_->first][fifth_->first]<<"  ";
    std::cout<<"i-j:"<<(this->distance_)[forth_->first][fifth_->first]<<"  \n"; */
    /*std::cout<<"i: "<<forth_->first<<"  ";
    std::cout<<"j: "<<fifth_->first<<"  ";
    std::cout<<"k: "<<third_->first<<"  \n";*/
    if((this->distance_)[forth_->first][third_->first]+(this->distance_)[third_->first][fifth_->first] < (this->distance_)[forth_->first][fifth_->first]){
     std::cout<<"enter"<<std::endl;
     (this->distance_)[forth_->first][fifth_->first] = this->distance_[forth_->first][third_->first] + this->distance_[fifth_->first][third_->first];
     (this->path_)[forth_->first][fifth_->first] = third_->first; //path存储从forth_到fifth_经过的结点. 
    }
   }
  }
 }
 
 /*typename std::map<T, std::map<T, T>>::const_iterator begin_ = (this->path_).begin();
 for(; begin_ != (this->path_).cend(); ++begin_){
  
  std::cout<<begin_->first<<":  ";
  typename std::map<T, T>::const_iterator end_ = (this->path_)[begin_->first].cbegin();
  for(; end_ != (this->path_)[begin_->first].cend(); ++end_){
   std::cout<<end_->first<<"--"<<end_->second<<"   ";
  }
  
  std::cout<<std::endl;
 }*/
}
template<typename T>
template<typename Ty>
void Graph<T>::print(const Ty& start, const Ty& end)
{
 this->floyd_warshall();
 
 this->print_path(start, end);
}
template<typename T>
template<typename Ty>
void Graph<T>::print_path(const Ty& start_, const Ty& end_)
{
 if(start_ == end_){
  throw std::runtime_error(std::string("there is no way"));
 }
 
 if(this->path_[start_][end_] == 0){
  std::cout<<end_<<"  ";
  
 }else{
  this->print_path(start_, this->path_[start_][end_]);
  this->print_path(this->path_[start_][end_], end_);
 }
}
template<typename T>
Graph<T>::~Graph()
{
 if(!this->graph_.empty()){
  this->graph_.clear();
 }
 
 if(!this->path_.empty()){
  this->path_.clear();
 }
 
 if(!this->distance_.empty()){
  this->distance_.clear();
 }
}
int main()
{
 int edges[15][3]={
 {1, 2, 2},
 {1, 4, 20},
 {2, 5, 1},
 {3, 1, 3},
 {4, 3, 8},
 {4, 6, 6},
 {4, 7, 4},
 {5, 3, 4},
 {5, 8, 3},
 {6, 3, 1},
 {7, 8, 1},
 {8, 6, 2},
 {8, 10, 2},
 {9, 7, 2},
 {10, 9, 1}
 };
 
 Graph<int> my_graph(edges);
 
 my_graph.print(1, 3);
 
 return 0; 
}

你可能感兴趣的:(floyd_warshall 算法.)