GRL_2_A 最小全域木(クラスカル)
# 目次
# 問題
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_2_A
# 解説
最小全域木はクラスカル法で簡単に求められる.
- 辺を重み昇順にソートする
- 重みの小さい辺から順に以下を実行する
- 辺の始点終点が異なる素集合に属していたら、辺を最小全域木に加える
- 最小全域木には最低限必要な辺のみが入っている.コストは合計すれば良い。
# 計算量
(辺のソート分の計算量)
# 解答
#define MAX_N 10001
#define W_INF (1 << 21)
class Edge {
public:
Int src, tgt, cost;
Edge(Int src, Int tgt, Int cost): src(src), tgt(tgt), cost(cost) {}
bool operator < ( const Edge &e) const {
return cost < e.cost;
}
};
class DisjointSet {
public:
DisjointSet(int n) {
rank.resize(n);
parent.resize(n);
for (int i=0; i<n; i++) rank[i] = 0, parent[i] = i;
}
bool same(int x, int y) {
return root(x) == root(y);
}
void unite(int x, int y) {
x = root(x), y = root(y);
if (rank[x] > rank[y]) {
parent[y] = x;
} else {
parent[x] = y;
if (rank[x] == rank[y]) rank[y]++;
}
}
private:
vector<int> rank;
vector<int> parent;
int root(int x) {
if (x != parent[x]) {
parent[x] = root(parent[x]);
}
return parent[x];
}
};
Int N;
vector<Edge> edges;
Int kruskal() {
Int total = 0;
sort(edges.begin(), edges.end());
DisjointSet dset(N);
for (auto edge: edges) {
if (!dset.same(edge.src, edge.tgt)) {
total += edge.cost;
dset.unite(edge.src, edge.tgt);
}
}
return total;
}
int main(void) {
int e, u, v, w;
cin >> N >> e;
while (cin >> u >> v >> w) {
edges.push_back(Edge(u, v, w));
}
cout << kruskal() << endl;
}