00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef DirectedGraph_h_DEFINED
00013 #define DirectedGraph_h_DEFINED
00014
00015 #include <stdio.h>
00016
00017 #include <list>
00018 #include <map>
00019 #include <set>
00020 using std::list;
00021 using std::map;
00022 using std::set;
00023 using std::multiset;
00024 using std::less;
00025
00026 template <class Node, class Arc>
00027 class DirectedGraph {
00028 private:
00029 map<Node, list<Arc>, less<Node> > graph_;
00030
00031 private:
00032 class Path {
00033 public:
00034 Path(const Arc& arc) {
00035 distance_ = arc.Distance();
00036 path_.push_back(arc);
00037 }
00038 ~Path() {}
00039
00040 void PushBack(const Arc& arc) {
00041 distance_ += arc.Distance();
00042 path_.push_back(arc);
00043 }
00044 void PopBack() {
00045 distance_ -= path_.back().Distance();
00046 path_.pop_back();
00047 }
00048
00049 const list<Arc>& ArcList() const { return path_; }
00050 int Distance() const { return distance_; }
00051 const Node& LatestNode() const { return (path_.back()).Destination(); }
00052
00053 friend bool operator< (const Path& a, const Path& b) {
00054 return (a.distance_ < b.distance_) ? true : false;
00055 }
00056
00057 private:
00058 int distance_;
00059 list<Arc> path_;
00060 };
00061
00062 public:
00063 DirectedGraph() {}
00064 ~DirectedGraph() {}
00065
00066 inline void Add(const Arc& arc);
00067 inline void Remove(const Arc& arc);
00068 inline int Search(const Node& src, const Node& dest, list<Arc>& path);
00069 inline void Print();
00070 };
00071
00072 template <class Node, class Arc>
00073 void
00074 DirectedGraph<Node, Arc>::Add(const Arc& arc)
00075 {
00076 ( graph_[arc.Source()] ).push_back(arc);
00077 }
00078
00079 template <class Node, class Arc>
00080 void
00081 DirectedGraph<Node, Arc>::Remove(const Arc& arc)
00082 {
00083 ( graph_[arc.Source()] ).remove(arc);
00084 }
00085
00086 template <class Node, class Arc>
00087 int
00088 DirectedGraph<Node, Arc>::Search(const Node& src,
00089 const Node& dest, list<Arc>& path)
00090 {
00091 set<Node, less<Node> > T;
00092 multiset<Path, less<Path> > F;
00093
00094 T.insert(src);
00095 typename list<Arc>::iterator iter = (graph_[src]).begin();
00096 typename list<Arc>::iterator last = (graph_[src]).end();
00097 while (iter != last) {
00098 F.insert(Path(*iter)); iter++;
00099 }
00100
00101 while (1) {
00102
00103 typename multiset<Path, less<Path> >::iterator path_iter = F.begin();
00104 if (path_iter == F.end()) {
00105
00106
00107 return -1;
00108
00109 } else if ( (*path_iter).LatestNode() == dest) {
00110
00111
00112 path = (*path_iter).ArcList();
00113 return (*path_iter).Distance();
00114 }
00115
00116 Path nearestPath = *path_iter; F.erase(path_iter);
00117 Node latestNode = nearestPath.LatestNode();
00118
00119 if (T.find(latestNode) == T.end()) {
00120
00121 T.insert(latestNode);
00122
00123 typename list<Arc>::iterator iter2 = graph_[latestNode].begin();
00124 typename list<Arc>::iterator last2 = graph_[latestNode].end();
00125 while (iter2 != last2) {
00126 if ( T.find((*iter2).Destination()) == T.end() ) {
00127 nearestPath.PushBack(*iter2);
00128 F.insert(nearestPath);
00129 nearestPath.PopBack();
00130 }
00131 ++iter2;
00132 }
00133 }
00134 }
00135 }
00136
00137 template <class Node, class Arc>
00138 void
00139 DirectedGraph<Node, Arc>::Print()
00140 {
00141 typename map<Node, list<Arc>, less<Node> >::iterator iter = graph_.begin();
00142 typename map<Node, list<Arc>, less<Node> >::iterator last = graph_.end();
00143 while (iter != last) {
00144 printf("Node ");
00145 (*iter).first.Print();
00146 printf(" : ");
00147 typename list<Arc>::iterator iter2 = (*iter).second.begin();
00148 typename list<Arc>::iterator last2 = (*iter).second.end();
00149 while (iter2 != last2) {
00150 (*iter2).Print();
00151 ++iter2;
00152 }
00153 printf("\n");
00154 ++iter;
00155 }
00156 }
00157
00158 #endif // DirectedGraph_h_DEFINED