既にある辺を使って最大全域森を作る。
その後は、新たな辺を付け足して連結にする。
kruskalを知っていれば簡単。
- class DisjointSet{
- public:
- vector<int> rank, p;
- DisjointSet(int size){
- rank.resize(size, 0);
- p.resize(size, 0);
- }
- void make(int a){
- rank[a] = 0;
- p[a] = a;
- }
- void join(int a, int b){
- link(find(a), find(b));
- }
- int find(int a){
- return (a == p[a])? a : p[a] = find(p[a]);
- }
- bool isSameSet(int a, int b){
- return find(a) == find(b);
- }
- void link (int a, int b){
- if(rank[a] > rank[b])
- p[b] = a;
- else{
- p[a] = b;
- if(rank[a] == rank[b])
- rank[b]++;
- }
- }
- };
- int no(char c)
- {
- if ('A' <= c && c <= 'Z') return c - 'A';
- if ('a' <= c && c <= 'z') return c - 'a' + 26;
- return -100;
- }
- class KingdomReorganization {
- public:
- int getCost(vector <string> K, vector <string> B, vector <string> D)
- {
- const int N = K.size();
- DisjointSet ds(N);
- for (int i = 0; i < N; ++i) {
- ds.make(i);
- }
- vector< pair<int, pair<int, int> > > v, u;
- for (int i = 0; i < N; ++i) {
- for (int j = i + 1; j < N; ++j) {
- if (K[i][j] == '0') {
- v.push_back(make_pair(no(B[i][j]), make_pair(i, j)));
- } else {
- u.push_back(make_pair(no(D[i][j]), make_pair(i, j)));
- }
- }
- }
- sort(v.begin(), v.end());
- sort(u.begin(), u.end());
- reverse(u.begin(), u.end());
- int sum = 0;
- for (int i = 0; i < u.size(); ++i) {
- pair<int, int> p = u[i].second;
- if (!ds.isSameSet(p.first, p.second)) {
- ds.join(p.first, p.second);
- } else sum += u[i].first;
- }
- for (int i = 0; i < v.size(); ++i) {
- pair<int, int> p = v[i].second;
- if (!ds.isSameSet(p.first, p.second)) {
- ds.join(p.first, p.second);
- sum += v[i].first;
- }
- }
- return sum;
- }
- };
0 件のコメント :
コメントを投稿