AOJ 0180 - Stellar Performance of the Debunkey Family(Kruskal法)
コードがながい.unique_ptrがつかってみたかったのだけど,使い所間違っているかなー.
kruskal法はむずかしいと思っていましたが,そうでもなかったです.
#include<iostream> #include<memory> #include<vector> #include<algorithm> class UnionFind{ private: int n; std::unique_ptr<int[]> par, rank; public: UnionFind(int n); int find(int x); void unite(int x, int y); bool same(int x, int y); }; UnionFind::UnionFind(int _n) :n(_n) { this->par.reset(new int[n]); this->rank.reset(new int[n]); for(int i=0;i<n;i++){ this->par[i] = i; this->rank[i] = 0; } } int UnionFind::find(int x){ if(x == this->par[x]){ return x; } return this->par[x] = find(par[x]); } void UnionFind::unite(int x, int y){ x = find(x); y = find(y); if(x == y){//すでに同じ return; } if(rank[x] < rank[y]){ par[x] = y; }else{ par[y] = x; if(rank[x] == rank[y]){ rank[x]++; } } } bool UnionFind::same(int x, int y){ return find(x) == find(y); } struct Edge{ int from, to, cost; }; bool comp(const Edge& l_edge, const Edge& r_edge){ return l_edge.cost < r_edge.cost; } const int MAX_N = 100, MAX_M = 100; const int INF = 1 << 24; int kruskal(int V, std::vector<Edge> &ev){ std::sort(ev.begin(), ev.end(), comp); UnionFind uf(V); int res = 0, ev_size = ev.size(); for(int i=0;i<ev_size;i++){ Edge e = ev[i]; if(!uf.same(e.from, e.to)){ uf.unite(e.from, e.to); res += e.cost; } } return res; } int main(){ int n, m; int cost[MAX_N][MAX_N]; while(std::cin >> n >> m, n){ std::vector<Edge> ev; for(int i=0;i<MAX_N;i++){ std::fill(cost[i], cost[i]+MAX_N, INF); } for(int i=0;i<m;i++){ int a, b, c; std::cin >> a >> b >> c; Edge e = {a, b, c}; ev.push_back(e); } std::cout << kruskal(n, ev) << std::endl; } }