00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _ADJ_LIST
00022 #define _ADJ_LIST
00023
00024 #include <ext/hash_map>
00025 #include <algorithm>
00026 #include <map>
00027 #include <sstream>
00028 #include <iostream>
00029
00030 using namespace std;
00031
00032
00033 template<typename VERTEX_T, typename EDGE_T, template <typename> class ALLOC> struct vertex_info;
00034 template<typename VERTEX_T, typename EDGE_T, template <typename> class ALLOC>
00035 ostream& operator<< (ostream&, const vertex_info<VERTEX_T, EDGE_T, ALLOC>&);
00036
00038 template<typename VERTEX_T, typename EDGE_T, template <typename> class ALLOC=std::allocator>
00039 struct vertex_info
00040 {
00041
00042 typedef pair<int, EDGE_T> EDGE_P;
00043 typedef vector<EDGE_P, ALLOC<EDGE_P> > EDGES;
00044 typedef typename EDGES::iterator EIT;
00045 typedef typename EDGES::const_iterator CONST_EIT;
00046
00047 vertex_info(const VERTEX_T& vert, const int& idval): v(vert), id(idval) {}
00049 EIT out_begin() {return out_edges.begin();}
00051 CONST_EIT out_begin() const {return out_edges.begin();}
00053 EIT out_end() {return out_edges.end();}
00055 CONST_EIT out_end() const {return out_edges.end();}
00056
00058 EIT in_begin() {return in_edges.begin();}
00060 CONST_EIT in_begin() const {return in_edges.begin();}
00062 EIT in_end() {return in_edges.end();}
00064 CONST_EIT in_end() const {return in_edges.end();}
00066 void add_out_edge(const int& dest, const EDGE_T& e)
00067 {
00068
00069 out_edges.push_back(make_pair(dest, e));
00070 }
00072 void add_in_edge(const int& src, const EDGE_T& e)
00073 {
00074
00075 in_edges.push_back(make_pair(src, e));
00076 }
00077
00082 bool out_edge(const int& dest, EDGE_T& e) const {
00083 CONST_EIT it;
00084 for(it=out_begin(); it!=out_end(); it++)
00085 if(it->first==dest) {
00086 e=it->second;
00087 return true;
00088 }
00089 return false;
00090 }
00091
00094 bool in_edge(const int& src, EDGE_T& e) const {
00095 CONST_EIT it;
00096 for(it=in_begin(); it!=in_end(); it++)
00097 if(it->first==src) {
00098 e=it->second;
00099 return true;
00100 }
00101 return false;
00102 }
00104 bool operator< (const vertex_info<VERTEX_T, EDGE_T, ALLOC>& vertex2) const {
00105
00106 if(v < vertex2.v)
00107 return true;
00108 else
00109 return false;
00110 }
00111
00113 friend ostream& operator<< <>(ostream&, const vertex_info<VERTEX_T, EDGE_T, ALLOC>&);
00114
00116 VERTEX_T v;
00117 int id;
00118 EDGES out_edges;
00119 EDGES in_edges;
00120
00121 };
00122
00123
00124 template<typename E_T>
00125 ostream& operator<< (ostream& ostr, const std::pair<int, E_T>& p) {
00126 ostr<<"("<<p.first<<" "<<p.second<<")";
00127 return ostr;
00128 }
00129
00130
00131 template<typename E_T>
00132 ostream& operator<< (ostream& ostr, const vector<pair<int, E_T> >& hm) {
00133 typename vector<pair<int, E_T> >::const_iterator it;
00134 for(it=hm.begin(); it!=hm.end(); it++)
00135 std::cout<<*it<<" ";
00136 return ostr;
00137 }
00138
00139
00140
00141 template<typename V_T, typename E_T>
00142 ostream& operator<< (ostream& ostr, const vertex_info<V_T, E_T>& vi) {
00143 ostr<<"["<<vi.id<<"|"<<vi.v<<"] OUT: ";
00144 typename vertex_info<V_T, E_T>::CONST_EIT it;
00145 ostr<<vi.out_edges;
00146 ostr<<" IN: ";
00147 ostr<<vi.in_edges;
00148 ostr<<endl;
00149 return ostr;
00150 }
00151
00152 template<typename V_T, typename E_T, template <typename> class ALLOC >
00153 class adj_list;
00154
00155 template<typename V_T, typename E_T, template <typename> class ALLOC >
00156 ostream& operator<< (ostream&, const adj_list<V_T, E_T, ALLOC>&);
00157
00164 template<typename V_T, typename E_T, template <typename> class ALLOC=std::allocator>
00165 class adj_list
00166 {
00167
00168 public:
00169 typedef V_T VERTEX_T;
00170 typedef E_T EDGE_T;
00171 typedef vertex_info<VERTEX_T, EDGE_T, ALLOC> VERTEX_INFO;
00172 typedef adj_list<V_T, E_T, ALLOC > ADJ_L;
00173
00174 template<typename T>
00175 class VERTEX_LIST: public std::vector<T, ALLOC<T> > {};
00176
00177 typedef VERTEX_LIST<VERTEX_INFO> ADJ_LIST;
00178
00179 typedef typename ADJ_LIST::iterator IT;
00180 typedef typename ADJ_LIST::const_iterator CONST_IT;
00181 typedef typename VERTEX_INFO::EIT EIT;
00182 typedef typename VERTEX_INFO::CONST_EIT CONST_EIT;
00183 typedef std::pair<EIT, EIT> EIT_PAIR;
00184 typedef std::pair<CONST_EIT, CONST_EIT> CONST_EIT_PAIR;
00185
00186 void* operator new(size_t size) {
00187 ALLOC<ADJ_L> aa;
00188 return aa.allocate(size);
00189 }
00190
00191 void operator delete(void *p, size_t size) {
00192 if (p) {
00193 ALLOC<ADJ_L> aa;
00194 aa.deallocate(static_cast<ADJ_L*> (p), size);
00195 }
00196 }
00197
00198
00199 adj_list() {}
00200
00201 IT begin() {return _alist.begin();}
00202 CONST_IT begin() const {return _alist.begin();}
00203 IT end() {return _alist.end();}
00204 CONST_IT end() const {return _alist.end();}
00205
00206 inline
00207 int size() const {return _alist.size();}
00208 void clear() {_alist.clear();}
00209 void push_back(const VERTEX_INFO& vi) {_alist.push_back(vi);}
00210
00212 IT vertex_vals(const int&);
00213
00214 CONST_IT vertex_vals(const int& idval) const {
00215 CONST_IT it=_alist.begin();
00216 if(idval>size()-1) {
00217 std::cerr<<"adj_list.vertex_vals: out of range vertex id, "<<idval<<endl;
00218 exit(0);
00219 }
00220 it+=idval;
00221 return it;
00222 }
00223
00226 std::pair<EIT, EIT> out_edges(const int& idval) {
00227 IT it=vertex_vals(idval);
00228 return make_pair(it->out_begin(), it->out_end());
00229 }
00230
00231 std::pair<CONST_EIT, CONST_EIT> out_edges(const int& idval) const {
00232 CONST_IT it=vertex_vals(idval);
00233 return make_pair(it->out_begin(), it->out_end());
00234 }
00235
00238 std::pair<EIT, EIT> in_edges(const int& idval) {
00239 IT it=vertex_vals(idval);
00240 return make_pair(it->in_begin(), it->in_end());
00241 }
00242
00243 std::pair<CONST_EIT, CONST_EIT> in_edges(const int& idval) const {
00244 CONST_IT it=vertex_vals(idval);
00245 return make_pair(it->in_begin(), it->in_end());
00246 }
00247
00249 int out_nbr_size(const int& vid) const {
00250 pair<CONST_EIT, CONST_EIT> out_pit=out_edges(vid);
00251 return out_pit.second-out_pit.first;
00252 }
00253
00255 int in_nbr_size(const int& vid) const {
00256 pair<CONST_EIT, CONST_EIT> in_pit=in_edges(vid);
00257 return in_pit.second-in_pit.first;
00258 }
00259
00262 int add_vertex(const VERTEX_T& v) {
00263 _alist.push_back(VERTEX_INFO(v, size()));
00264 return size()-1;
00265 }
00266
00268 void add_out_edge(const int& src, const int& dest, const EDGE_T& e) {
00269 if((src>size()-1) || (dest>size()-1)) {
00270 std::cerr<<"adj_list::add_out_edge:out of bound vertex IDs, src="<<src<<" dest="<<dest<<" size()="<<_alist.size()<<endl;
00271 exit(0);
00272 }
00273
00274 IT it=vertex_vals(src);
00275 it->add_out_edge(dest, e);
00276
00277 }
00278
00280 void add_in_edge(const int& dest, const int& src, const EDGE_T& e) {
00281 if((src>size()-1) || (dest>size()-1)) {
00282 std::cerr<<"adj_list::add_in_edge:out of bound vertex IDs, src="<<src<<" dest="<<dest<<" size()="<<_alist.size()<<endl;
00283 exit(0);
00284 }
00285
00286 IT it=vertex_vals(dest);
00287 it->add_in_edge(src, e);
00288
00289 }
00290
00291
00294 bool get_out_edge(const int& src, const int& dest, EDGE_T& e) const {
00295 CONST_IT it=vertex_vals(src);
00296 return it->out_edge(dest, e);
00297 }
00298
00301 bool get_in_edge(const int& src, const int& dest, EDGE_T& e) const {
00302 CONST_IT it=vertex_vals(src);
00303 return it->in_edge(dest, e);
00304 }
00305
00306
00307 friend ostream& operator<< <>(ostream&, const adj_list<V_T, E_T, ALLOC>&);
00308
00309 private:
00310 ADJ_LIST _alist;
00311
00312
00313 };
00314
00315
00316
00317 template<typename V_T, typename E_T, template <typename> class ALLOC>
00318 ostream& operator<< (ostream& ostr, const adj_list<V_T, E_T, ALLOC>& al) {
00319 typename adj_list<E_T, V_T, ALLOC>::CONST_IT it=al.begin();
00320 while(it!=al.end()) {
00321 ostr<<*it;
00322 it++;
00323 }
00324 ostr<<"---";
00325 return ostr;
00326 }
00327
00328 template<typename V_T, typename E_T, template <typename> class ALLOC >
00329 typename adj_list<V_T, E_T, ALLOC>::IT adj_list<V_T, E_T, ALLOC>::vertex_vals(const int& idval) {
00330 typename adj_list<V_T, E_T, ALLOC>::IT it=_alist.begin();
00331 if(idval>size()-1) {
00332 std::cerr<<"adj_list.vertex_vals: out of range vertex id, "<<idval<<endl;
00333 exit(0);
00334 }
00335 it+=idval;
00336 return it;
00337 }
00338
00339
00340 #endif