beckerjc@150
|
1 |
// -*- c++ -*- //
|
beckerjc@150
|
2 |
#ifndef HUGO_KRUSKAL_H
|
beckerjc@150
|
3 |
#define HUGO_KRUSKAL_H
|
beckerjc@150
|
4 |
|
beckerjc@150
|
5 |
#include "unionfind.h"
|
beckerjc@150
|
6 |
#include <algorithm>
|
beckerjc@150
|
7 |
|
beckerjc@150
|
8 |
namespace hugo {
|
beckerjc@150
|
9 |
|
beckerjc@150
|
10 |
|
beckerjc@218
|
11 |
template <typename Graph, typename EdgeCostMap, typename EdgeBoolMap>
|
beckerjc@218
|
12 |
class MinCostTreeKruskal
|
beckerjc@218
|
13 |
{
|
beckerjc@150
|
14 |
|
beckerjc@218
|
15 |
typedef typename Graph::EdgeIt EdgeIt;
|
beckerjc@218
|
16 |
typedef typename Graph::Edge Edge;
|
beckerjc@150
|
17 |
|
beckerjc@218
|
18 |
public:
|
beckerjc@218
|
19 |
typedef typename EdgeCostMap::ValueType EdgeCost;
|
beckerjc@218
|
20 |
typedef std::pair<Edge, EdgeCost> EdgeCostPair;
|
beckerjc@218
|
21 |
typedef std::vector<EdgeCostPair> EdgeCostVector;
|
beckerjc@150
|
22 |
|
beckerjc@218
|
23 |
private:
|
beckerjc@218
|
24 |
Graph const &G;
|
beckerjc@218
|
25 |
EdgeCostMap const &costmap;
|
beckerjc@218
|
26 |
EdgeBoolMap& treemap;
|
beckerjc@218
|
27 |
|
beckerjc@218
|
28 |
//template <typename EdgeCostPair>
|
beckerjc@218
|
29 |
class comparePair {
|
beckerjc@218
|
30 |
public:
|
beckerjc@218
|
31 |
bool operator()(EdgeCostPair const& a, EdgeCostPair const& b) {
|
beckerjc@218
|
32 |
return a.second < b.second;
|
beckerjc@218
|
33 |
}
|
beckerjc@218
|
34 |
};
|
beckerjc@150
|
35 |
|
beckerjc@218
|
36 |
public:
|
beckerjc@150
|
37 |
|
beckerjc@150
|
38 |
|
beckerjc@218
|
39 |
MinCostTreeKruskal(Graph const& _G, EdgeCostMap const& _costmap,
|
beckerjc@218
|
40 |
EdgeBoolMap& _treemap) : G(_G), costmap(_costmap),
|
beckerjc@218
|
41 |
treemap(_treemap) {}
|
beckerjc@218
|
42 |
|
beckerjc@218
|
43 |
|
beckerjc@218
|
44 |
EdgeCost run()
|
beckerjc@218
|
45 |
{
|
beckerjc@218
|
46 |
EdgeCostVector rank;
|
beckerjc@218
|
47 |
for (EdgeIt e=G.template first<EdgeIt>(); G.valid(e); G.next(e)) {
|
beckerjc@218
|
48 |
rank.push_back(make_pair(e, costmap.get(e)));
|
beckerjc@218
|
49 |
}
|
beckerjc@218
|
50 |
|
beckerjc@218
|
51 |
std::sort(rank.begin(), rank.end(), comparePair());
|
beckerjc@218
|
52 |
|
beckerjc@218
|
53 |
return run(rank);
|
beckerjc@218
|
54 |
|
beckerjc@150
|
55 |
}
|
beckerjc@150
|
56 |
|
beckerjc@218
|
57 |
EdgeCost run(EdgeCostVector const &rank)
|
beckerjc@218
|
58 |
{
|
beckerjc@218
|
59 |
typedef typename Graph::NodeMap<int> NodeIntMap;
|
beckerjc@218
|
60 |
typedef typename Graph::Node Node;
|
beckerjc@218
|
61 |
NodeIntMap comp_map(G, -1);
|
beckerjc@218
|
62 |
UnionFind<Node,NodeIntMap> uf(comp_map);
|
beckerjc@218
|
63 |
|
beckerjc@218
|
64 |
EdgeCost tot_cost = 0;
|
beckerjc@218
|
65 |
for (typename EdgeCostVector::const_iterator p = rank.begin();
|
beckerjc@218
|
66 |
p!=rank.end(); ++p ) {
|
beckerjc@218
|
67 |
if ( uf.joinComponents(G.head(p->first), G.tail(p->first)) ) {
|
beckerjc@218
|
68 |
treemap.set(p->first, true);
|
beckerjc@218
|
69 |
tot_cost += p->second;
|
beckerjc@218
|
70 |
}
|
beckerjc@218
|
71 |
else {
|
beckerjc@218
|
72 |
treemap.set(p->first, false);
|
beckerjc@218
|
73 |
}
|
beckerjc@218
|
74 |
}
|
beckerjc@218
|
75 |
return tot_cost;
|
beckerjc@150
|
76 |
|
beckerjc@218
|
77 |
}
|
beckerjc@150
|
78 |
|
beckerjc@218
|
79 |
};
|
beckerjc@150
|
80 |
|
beckerjc@150
|
81 |
|
beckerjc@150
|
82 |
} //namespace hugo
|
beckerjc@150
|
83 |
|
beckerjc@150
|
84 |
#endif //HUGO_KRUSKAL_H
|