• quick_fond算法, quick_union算法, weighted_quick_union算法, weighted_quick_union_with_path_comperession算法, 森林,并查集,朋友圈问题


    题目描述

    ​ 所谓一个朋友圈子,不一定其中的人都互相直接认识。
    ​ 例如:小张的朋友是小李,小李的朋友是小王,那么他们三个人属于一个朋友圈。
    ​ 现在给出一些人的朋友关系,人按照从 1到 n编号在这中间会进行询问某两个人是否属于一个朋友圈,请你编写程序,实现这个过程。

    输 入

    第一行输入两个整数 n,m(1≤n≤10000,3≤m≤100000),分别代表人数和操作数。
    接下来 m行,每行三个整 a,b,c(a∈[1,2], 1≤b,c≤n)当 a=1时,代表新增一条已知信息,b,c是朋友当 a=2
    时,代表根据以上信息,询问 b,c是否是朋友

    输 出

    对于每个 a=2 的操作,输出『Yes』或『No』
    代表询问的两个人是否是朋友关系。

    样例输入

    6 5
    1 1 2
    2 1 3
    1 2 4
    1 4 3
    2 1 3
    

    样例输出

    No
    Yes
    

    quick_find算法

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct unionSet {
            int *color, n;
    }UnionSet;
    
    UnionSet *init(int n) {
            UnionSet *u = (UnionSet *)malloc(sizeof(UnionSet));
            u->color = (int *)malloc(sizeof(int) * n);
            u->n = n;
            for (int i = 0; i < n; i++) u->color[i] = i;
            return u;
    }
    
    int fine(UnionSet *u, int n) {
            if (!u) return -1;
            return u->color[n];
    }
    
    int merge(UnionSet *u, int j1, int j2) {
            if (!u) return -1;
            int temp = u->color[j1];
            for (int i = 0; i < u->n; i++) u->color[i] - temp || (u->color[i] = u->color[j2]);
            return 1;
    }
    
    void clear(UnionSet *u) {
            if (!u) return ;
            free(u->color);
            free(u);
            return ;
    }
    
    int main() {
            int n, m, a, b, c;
            scanf("%d%d", &n, &m);
            UnionSet *u = init(n);
            for (int i = 0; i < m; i++) {
                    scanf("%d%d%d", &a, &b, &c);
                    --b, --c;
                    a ^ 1 && printf("%s
    ", fine(u, b) ^ fine(u, c) ? "No" : "Yes") || merge(u, b, c);
            }
            clear(u);
            return 0;
    }
    
    

    quick_union算法

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct unionSet {
            int *father, n;
    }UnionSet;
    
    UnionSet *init(int n) {
            UnionSet *u = (UnionSet *)malloc(sizeof(UnionSet));
            u->father = (int *)malloc(sizeof(int) * n);
            u->n = n;
            for (int i = 0; i < n; i++) u->father[i] = i;
            return u;
    }
    
    int find(UnionSet *u, int n) {
            if (u->father[n] - n) return find(u, u->father[n]);
            return n;
    }
    
    int merge(UnionSet *u, int j1, int j2) {
            if (!u) return -1;
            int temp1 = find(u, j1), temp2 = find(u, j2);
            temp1 - temp2 && (u->father[temp1] = u->father[temp2]);
            return 1;
    }
    
    void clear(UnionSet *u) {
            if (!u) return ;
            free(u->father);
            free(u);
            return ;
    }
    
    int main() {
            int n, m, a, b, c;
            scanf("%d%d", &n, &m);
            UnionSet *u = init(n);
            for (int i = 0; i < m; i++) {
                    scanf("%d%d%d", &a, &b, &c);
                    --b, --c;
                    a ^ 1 && printf("%s
    ", find(u, b) ^ find(u, c) ? "No" : "Yes") || merge(u, b, c);
            }
            clear(u);
            return 0;
    }
    
    

    weighted_quick_union算法

    #include <stdio.h>
    #include <stdlib.h>
    
    #define swap(a, b) ({
                    __typeof(a) __temp = a;
                    a = b, b = __temp;
                    })
    
    typedef struct unionSet {
            int *father, *size, n;
    }UnionSet;
    
    UnionSet *init(int n) {
            UnionSet *u = (UnionSet *)malloc(sizeof(UnionSet));
            u->father = (int *)malloc(sizeof(int) * n);
            u->size = (int *)malloc(sizeof(int) * n);
            u->n = n;
            for (int i = 0; i < n; i++) u->father[i] = i, u->size[i] = 1;
            return u;
    }
    
    int find(UnionSet *u, int n) {
            if (u->father[n] - n) return find(u, u->father[n]);
            return n;
    }
    
    int merge(UnionSet *u, int j1, int j2) {
            if (!u) return -1;
            int temp1 = find(u, j1), temp2 = find(u, j2);
            temp1 - temp2 && u->size[temp1] > u->size[temp2] && swap(temp1, temp2);
            temp1 - temp2 && (u->father[temp1] = temp2, u->size[temp2] += u->size[temp1]);
            return 1;
    }
    
    void clear(UnionSet *u) {
            if (!u) return ;
            free(u->father);
            free(u);
            return ;
    }
    
    int main() {
            int n, m, a, b, c;
            scanf("%d%d", &n, &m);
            UnionSet *u = init(n);
            for (int i = 0; i < m; i++) {
                    scanf("%d%d%d", &a, &b, &c);
                    --b, --c;
                    a ^ 1 && printf("%s
    ", find(u, b) ^ find(u, c) ? "No" : "Yes") || merge(u, b, c);
            }
            clear(u);
            return 0;
    }
    
    

    weighted_quick_union_with_path_comperession算法

    #include <stdio.h>
    #include <stdlib.h>
    
    #define swap(a, b) ({
                    __typeof(a) __temp = a;
                    a = b, b = __temp;
                    })
    
    typedef struct unionSet {
            int *father, *size, n;
    }UnionSet;
    
    UnionSet *init(int n) {
            UnionSet *u = (UnionSet *)malloc(sizeof(UnionSet));
            u->father = (int *)malloc(sizeof(int) * n);
            u->size = (int *)malloc(sizeof(int) * n);
            u->n = n;
            for (int i = 0; i < n; i++) u->father[i] = i, u->size[i] = 1;
            return u;
    }
    
    int find(UnionSet *u, int n) {
            return u->father[n] - n ? (u->father[n] = find(u, u->father[n])) : n;
    }
    
    int merge(UnionSet *u, int j1, int j2) {
            if (!u) return -1;
            int temp1 = find(u, j1), temp2 = find(u, j2);
            temp1 - temp2 && u->size[temp1] > u->size[temp2] && swap(temp1, temp2);
            temp1 - temp2 && (u->father[temp1] = temp2, u->size[temp2] += u->size[temp1]);
            return 1;
    }
    
    void clear(UnionSet *u) {
            if (!u) return ;
            free(u->father);
            free(u);
            return ;
    }
    
    int main() {
            int n, m, a, b, c;
            scanf("%d%d", &n, &m);
            UnionSet *u = init(n);
            for (int i = 0; i < m; i++) {
                    scanf("%d%d%d", &a, &b, &c);
                    --b, --c;
                    a ^ 1 && printf("%s
    ", find(u, b) ^ find(u, c) ? "No" : "Yes") || merge(u, b, c);
            }
            clear(u);
            return 0;
    }
    
  • 相关阅读:
    左耳听风-ARTS-第4周(2019/4/21-2019/4/27)
    Java集合总结
    Zuul网关总结
    左耳听风-ARTS-第3周(2019/4/7-2019/4/13)
    左耳听风-ARTS-第2周(2019/3/31-2019/4/6)
    Java泛型相关总结(下)
    左耳听风-ARTS-第1周
    去长江边走走,看看
    第1记
    c#发送邮件
  • 原文地址:https://www.cnblogs.com/hhhahh/p/15143843.html
Copyright © 2020-2023  润新知