有向图的单源最短路径

#include <iostream>
#include <queue>
#include <stdexcept> //throw std::runtime_error("xx");
#include <initializer_list>
#include <map>
template<typename T>
struct Edge{
 T start_;
 T end_;
 
 int weighting_;
 
 Edge()=default;
 
 template<typename Ty>
 Edge(const Ty& start, const Ty& end, const int& wg);
 
 template<typename Ty>
 Edge(const Edge<Ty>& otherEdge);
 
 ~Edge()=default;
};
template<typename T>
template<typename Ty>
Edge<T>::Edge(const Ty& start, const Ty& end, const int& wg)
        :start_(start),
         end_(end),
         weighting_(wg)
{
 //
}
template<typename T>
template<typename Ty>
Edge<T>::Edge(const Edge<Ty>& otherEdge)
        :start_(otherEdge.start_),
         end_(otherEdge.end_),
         weighting_(otherEdge.weighting_)
{
 //
}
class Compare{ //Compare用于prioprity_queue中的比较参数. 
 public:
  template<typename Ty>
  bool operator()(const Ty& first_, const Ty& second_)
  {
   return first_ < second_ ? true : false;
  }
};
template<typename T>
class Graph{
 private:
  Edge<T>* edgeArray; //store the start-node and end-node, the weighting between start-node and end-node;
  std::map<T, bool> visited_; //每个顶点都对应一个bool值, 访问过的话该bool值会被设置为true; 
  std::map<T, std::vector<T>> edges_; //邻接链表.即,每一个顶点与其他顶点相接,其他顶点都被放在vector<T>中. 
  std::priority_queue<T, std::vector<T>, Compare> cycle_; //如果该顶点有环路那么吧该顶点放入到cycle_; 
  std::map<T, bool> haveCycle_; //判断该点时候存在环路. 
  //std::multimap<T, T> edgeTo_;
  std::vector<T> result_;
  int edgeNumber_;
  bool flag_; //判断该有向加权图中是否存在回路.默认为true; 
  
  public:
   template<typename Ty>
   using iter = typename std::map<Ty, bool>::iterator;
      
   template<typename Ty, unsigned int N>
   Graph(const Ty (&edges)[N][3]);
   
   template<typename Ty>
   void dfs(const Ty& node_);
   
   void helperFunction();
   
   void print();
   
   ~Graph();
};
template<typename T>
template<typename Ty, unsigned int N>
Graph<T>::Graph(const Ty (&edges)[N][3])
         :edgeArray(nullptr),
          edgeNumber_(N),
          flag_(true)
{
 if( N == 0 ){
  std::runtime_error("The Graph has cycle.\n");
 }
 
 this->edgeArray = new Edge<Ty>[N]; //存储有向图的各个条边以及该边的加权值. 
 
 for(int i=0; i<N; ++i){ //存储有向加权图,且存储有向加权图的每一个结点.默认都是未被访问过的因此其对应的值为false. 
  
  Edge<Ty> edge(edges[i][0], edges[i][1], edges[i][2]);
  this->edgeArray[i] = edge;
  
  this->visited_[edges[i][0]] = false;
  this->visited_[edges[i][1]] = false;
  
  //this->haveCycle_[edges[i][0]] = false;
  //this->haveCycle_[edges[i][1]] = false;
  
  this->edges_[edges[i][0]].push_back(edges[i][1]); //邻接链表.即每个结点与其他结点相接,其他结点都被放在与该结点对应的std::vector中. 
 }
 
 std::cout<<"out of constructor fucntion"<<std::endl;
 
 /*iter<Ty> it = this->haveCycle_.begin();
 for(; it!=this->haveCycle_.end(); ++it){
  std::cout<<it->first<<std::endl;
 }*/
 
 
}
 
template<typename T>
template<typename Ty>
void Graph<T>::dfs(const Ty& node_) //该算法是基于深度优先遍历的. 
{
 
 std::cout<<"node: "<<node_<<std::endl;
 this->visited_[node_] = true; //当前结点已经被访问.把其对应的属性设置为true; 
 this->haveCycle_[node_] = true; //haveCycle_是一个存放具有环路结点的容器. 
 
 int temp = this->edges_[node_].size(); //获得与该结点相接的结点的个数. 
 for(int i=0; i<temp; ++i){
  if( !this->flag_ ){
   return;
  }
  
  if( !this->visited_[this->edges_[node_][i]] ){
   //this->edgeTo_[this->edges_[node_][i]] = node_;
   this->dfs(this->edges_[node_][i]);
   
  }else if(this->haveCycle_[this->edges_[node_][i]]){
   
   this->flag_ = false;
   std::cout<<"have cycle"<<std::endl;
   this->cycle_.push(node_);
   this->cycle_.push(this->edges_[node_][i]);
  }
 }
 
 this->result_.push_back(node_);
 this->haveCycle_[node_] = false;
 
}
template<typename T>
void Graph<T>::helperFunction()
{
 Graph<T>::iter<T> it = this->visited_.begin();
 
 for(; it != this->visited_.end(); ++it){
  
  if( !this->visited_[it->first] ){
   
   this->dfs(it->first);
  }
 }
}
template<typename T>
void Graph<T>::print()
{
 if( !this->flag_ ){
  std::cout<<"failed"<<std::endl;
  
 }else{
  std::cout<<"successful"<<std::endl;
  
  Graph<T>::iter<T> it = this->haveCycle_.begin();
  
  for(; it!=haveCycle_.end(); ++it){
   std::cout<<it->first<<std::endl;
  }
 }
}
template<typename T>
Graph<T>::~Graph()
{
 if(this->edgeArray != nullptr ){
  delete[] edgeArray;
 }
 
 if( !this->visited_.empty() ){
  this->visited_.clear();
 }
 
 if( !this->edges_.empty() ){
  this->edges_.clear();
 }
 
 if( !this->haveCycle_.empty() ){
  this->haveCycle_.clear();
 }
 
 
}
int main()
{
 int edge[][3]={ {0,2, 6}, {0,6, 6}, {2,6, 7}, {2,5, 4}, {2,4, 2}, {6,5 -1}, {6,4, 1}, {5,4, -2}};
 Graph<int> myGraph(edge);
 myGraph.helperFunction();
 myGraph.print();
 return 0;
}

转载于:https://my.oschina.net/SHIHUAMarryMe/blog/605665

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值