ホームに戻る
最小全域木

// クラスカル法
// コストの小さい枝から評価していく、
// このとき枝を繋いでループにならなければ繋ぐ。
// 全ての枝についてこれを行えば最小全域木になる。
// ループになるかどうかの検出はUnion-Findを用いる。
// O(E+VlogV)

vector<int> uf, usz;
int nc;
  
void init(int n){
  vector<int> uf_(n);
  vector<int> usz_(n, 1);
  uf = uf_;
  usz = usz_;
  nc = n;

  for(int i = 0; i < uf.size(); i++){
    uf[i] = i;
  }
}
  
int find(int a){
  return (uf[a] == a) ? a : uf[a] = find(uf[a]);
}
  
void union_(int a, int b){
  a = find(a);
  b = find(b);
  
  if(a != b){
    if(usz[a] >= usz[b]){
      swap(a, b);
    }
    uf[a] = b;
    usz[b] += usz[a];
    nc--;
  }
}
  
int check(int a, int b){
  return (find(a) == find(b)) ? 1 : 0;
}
  
int get_size(int a){
  return usz[find(a)];
}

// vector<pair<コスト,pair<元,先> > > であること
long long minST(vector<pair<long long,pair<long long, long long> > > &v, long long V){
  init(V);
  long long ret = 0;
  sort(v.begin(),v.end());
  for(long long i = 0; i < v.sz; i++){
    long long from = v[i].se.fi;
    long long to = v[i].se.se;
    long long cost = v[i].fi;
    if(check(from,to)==0){
      union_(from,to);
      ret += cost;
    }
  }
  return ret;
}

inserted by FC2 system