00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef LEMON_KRUSKAL_H
00018 #define LEMON_KRUSKAL_H
00019
00020 #include <algorithm>
00021 #include <lemon/unionfind.h>
00022 #include<lemon/utility.h>
00023
00034
00035
00036
00037
00038
00039
00040
00041
00042 namespace lemon {
00043
00046
00048
00102
00103 #ifdef DOXYGEN
00104 template <class GR, class IN, class OUT>
00105 typename IN::value_type::second_type
00106 kruskal(GR const& g, IN const& in,
00107 OUT& out)
00108 #else
00109 template <class GR, class IN, class OUT>
00110 typename IN::value_type::second_type
00111 kruskal(GR const& g, IN const& in,
00112 OUT& out,
00113
00114
00115
00116 const typename IN::value_type::first_type * =
00117 (const typename IN::value_type::first_type *)(0),
00118 const typename OUT::Key * = (const typename OUT::Key *)(0)
00119 )
00120 #endif
00121 {
00122 typedef typename IN::value_type::second_type EdgeCost;
00123 typedef typename GR::template NodeMap<int> NodeIntMap;
00124 typedef typename GR::Node Node;
00125
00126 NodeIntMap comp(g, -1);
00127 UnionFind<Node,NodeIntMap> uf(comp);
00128
00129 EdgeCost tot_cost = 0;
00130 for (typename IN::const_iterator p = in.begin();
00131 p!=in.end(); ++p ) {
00132 if ( uf.join(g.target((*p).first),
00133 g.source((*p).first)) ) {
00134 out.set((*p).first, true);
00135 tot_cost += (*p).second;
00136 }
00137 else {
00138 out.set((*p).first, false);
00139 }
00140 }
00141 return tot_cost;
00142 }
00143
00144
00146
00147
00148
00149
00151
00162 template<class Map>
00163 class NonConstMapWr {
00164 const Map &m;
00165 public:
00166 typedef typename Map::Key Key;
00167 typedef typename Map::Value Value;
00168
00169 NonConstMapWr(const Map &_m) : m(_m) {}
00170
00171 template<class Key>
00172 void set(Key const& k, Value const &v) const { m.set(k,v); }
00173 };
00174
00175 template <class GR, class IN, class OUT>
00176 inline
00177 typename IN::value_type::second_type
00178 kruskal(GR const& g, IN const& edges, OUT const& out_map,
00179
00180
00181 const typename IN::value_type::first_type * =
00182 (const typename IN::value_type::first_type *)(0),
00183 const typename OUT::Key * = (const typename OUT::Key *)(0)
00184 )
00185 {
00186 NonConstMapWr<OUT> map_wr(out_map);
00187 return kruskal(g, edges, map_wr);
00188 }
00189
00190
00191
00193
00208 template<class GR, class Map>
00209 class KruskalMapInput
00210 : public std::vector< std::pair<typename GR::Edge,
00211 typename Map::Value> > {
00212
00213 public:
00214 typedef std::vector< std::pair<typename GR::Edge,
00215 typename Map::Value> > Parent;
00216 typedef typename Parent::value_type value_type;
00217
00218 private:
00219 class comparePair {
00220 public:
00221 bool operator()(const value_type& a,
00222 const value_type& b) {
00223 return a.second < b.second;
00224 }
00225 };
00226
00227 template<class _GR>
00228 typename enable_if<typename _GR::UndirTag,void>::type
00229 fillWithEdges(const _GR& g, const Map& m,dummy<0> = 0)
00230 {
00231 for(typename GR::UndirEdgeIt e(g);e!=INVALID;++e)
00232 push_back(value_type(typename GR::Edge(e,true), m[e]));
00233 }
00234
00235 template<class _GR>
00236 typename disable_if<typename _GR::UndirTag,void>::type
00237 fillWithEdges(const _GR& g, const Map& m,dummy<1> = 1)
00238 {
00239 for(typename GR::EdgeIt e(g);e!=INVALID;++e)
00240 push_back(value_type(e, m[e]));
00241 }
00242
00243
00244 public:
00245
00246 void sort() {
00247 std::sort(this->begin(), this->end(), comparePair());
00248 }
00249
00250 KruskalMapInput(GR const& g, Map const& m) {
00251 fillWithEdges(g,m);
00252 sort();
00253 }
00254 };
00255
00257
00275 template<class GR, class Map>
00276 inline
00277 KruskalMapInput<GR,Map> makeKruskalMapInput(const GR &g,const Map &m)
00278 {
00279 return KruskalMapInput<GR,Map>(g,m);
00280 }
00281
00282
00283
00284
00285
00286
00287
00289
00312
00313 template<class Iterator>
00314 class KruskalSequenceOutput {
00315 mutable Iterator it;
00316
00317 public:
00318 typedef typename Iterator::value_type Key;
00319 typedef bool Value;
00320
00321 KruskalSequenceOutput(Iterator const &_it) : it(_it) {}
00322
00323 template<typename Key>
00324 void set(Key const& k, bool v) const { if(v) {*it=k; ++it;} }
00325 };
00326
00327 template<class Iterator>
00328 inline
00329 KruskalSequenceOutput<Iterator>
00330 makeKruskalSequenceOutput(Iterator it) {
00331 return KruskalSequenceOutput<Iterator>(it);
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 template <class GR, class IN, class RET>
00361 inline
00362 typename IN::Value
00363 kruskal(GR const& g,
00364 IN const& in,
00365 RET &out,
00366
00367
00368
00369 const typename IN::Key * = (const typename IN::Key *)(0),
00370 const typename RET::Key * = (const typename RET::Key *)(0)
00371 )
00372 {
00373 return kruskal(g,
00374 KruskalMapInput<GR,IN>(g,in),
00375 out);
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 template <class GR, class IN, class RET>
00413 inline
00414 typename IN::Value
00415 kruskal(const GR& g,
00416 const IN& in,
00417 RET out,
00418
00419
00420 const typename RET::value_type * =
00421 (const typename RET::value_type *)(0)
00422 )
00423 {
00424 KruskalSequenceOutput<RET> _out(out);
00425 return kruskal(g, KruskalMapInput<GR,IN>(g, in), _out);
00426 }
00427
00429
00430 }
00431
00432 #endif //LEMON_KRUSKAL_H