1. 程式人生 > 其它 >朋友圈問題, quick_fond演算法, 森林,並查集

朋友圈問題, quick_fond演算法, 森林,並查集

題目描述

​ 所謂一個朋友圈子,不一定其中的人都互相直接認識。
​ 例如:小張的朋友是小李,小李的朋友是小王,那麼他們三個人屬於一個朋友圈。
​ 現在給出一些人的朋友關係,人按照從 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
#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\n", fine(u, b) ^ fine(u, c) ? "No" : "Yes") || merge(u, b, c);
        }
        clear(u);
        return 0;
}