And check the set-Legend of the Galactic Heroes (nkoj1206)

And check the set - Legend of the Galactic Heroes ( nkoj1206 )

topic analysis

Merge and query whether nodes are operating in the same heap, while maintaining the node spacing, using the merge set with serial number

And check the set (with serial number)

First understand the problem that union-find solves: the dynamic connectivity problem, that is 把p和q所在的堆合并,看p和q在不在同一堆

First make all points belong to different groups:father[i]=i

Then the most naive basic operations:

    int get_father(int x) {
        father[x] = get_father(father[x]);
    }

    void merge(int x, int y) {
        father[get_father(x)] = get_father(y);
    }

Then there are several possible extension operations:

  • Maintain heap size (parent's heap grows when merging)
    void merge(int x, int y) {
        x = get_father(x);
        y = get_father(y);
        if (x != y) {
            father[x] = y;
            size[y] += size[x];
        }
    }
  • Maintain the serial number (the son's rank becomes larger when merging, and the rank is updated before the path is compressed when get_father)
    int get_father(int x) {
        if (father[x] == x) {
            return x;
        } else {
            int tmp = get_father(father[x]);
            rank[x] += rank[father[x]];
            father[x] = tmp;
            return father[x];
        }
    }

    void merge(int x, int y) {
        x = get_father(x);
        y = get_father(y);
        if (x != y) {
            father[x] = y;
            rank[x] += size[y];
            size[y] += size[x];
        }
    }

This question can maintain the serial number, and the difference between ranks is the node spacing

code

//
// Created by rv on 2018/4/20.
//

#include "iostream"
#include "cstdio"

using namespace std;
int T, i, j;
char ins;

struct UF {
    int count;
    int* father;
    int* size;
    int* rank;
    UF(int t) {
        count  = t;
        father = new int[t];
        size = new int[t];
        rank = new int[t];
        for (int i = 0; i < t; i++) {
            father[i] = i;
            size[i] = 1;
            rank[i] = 0;
        }
    }
    int get_father(int x) {
        if (father[x] == x) {
            return x;
        } else {
            int tmp = get_father(father[x]);
            rank[x] += rank[father[x]];
            father[x] = tmp;
            return father[x];
        }
    }
    void merge(int x, int y) {
        x = get_father(x);
        y = get_father(y);
        if (x != y) {
            father[x] = y;
            rank[x] += size[y];
            size[y] += size[x];
        }
    }
    int call(int x, int y) {
        if (get_father(x) != get_father(y)) {
            return -1;
        } else {
            return abs(rank[x] - rank[y]) - 1;
        }
    }
    void print() {
        printf("father: ");
        for (int i = 0; i < count; i++) {
            printf("%d ", father[i]);
        }
        printf("\n");
        printf("size: ");
        for (int i = 0; i < count; i++) {
            printf("%d ", size[i]);
        }
        printf("\n");
        printf("rank: ");
        for (int i = 0; i < count; i++) {
            printf("%d ", rank[i]);
        }
        printf("\n");
    }
};

int main() {
//    freopen("1206/data2.in", "r", stdin);
//    freopen("data2.out", "w", stdout);
    scanf("%d", &T);
    UF uf(T + 1);
    while(T--) {
        scanf("%s%d%d", &ins, &i, &j);
//        printf("%c %d %d\n", ins, i, j);
        if (ins == 'M') {
            uf.merge(i, j);
        }
        if (ins == 'C') {
            printf("%d\n", uf.call(i, j));
        }
//        uf.print();
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325753986&siteId=291194637