• 【Atcoder】ABC183 F Confluence 并查集+启发式合并


    题目链接

    题意

    现在有 n 个学生,第 i 个学生所在班级为 \(c_i\)

    现在他们要去上学,某个学生在去上学的路上可能会遇到其他的学生并加入到该集合。

    现在有两种操作:

    1. x y,表示第 x 个学生所在集合和第 y 个学生所在集合相遇
    2. x y 表示查询和第 x 个学生在同一个集合中 y 班级的学生。

    思路

    第一个很明显是并查集,但第二个查询却不好解决。

    首先不可能维护每个集合中所有班级的学生数量,数组都开不了这么大。

    稍微优化一下,只维护出现在该集合中的班级的学生数量。

    那合并的时候我们怎么办呢?

    启发式合并

    暴力将集合较小的合并到较大的中去。

    使用一个二维map来维护每个集合中出现了那些班级以及这些班级的学生数量。

    代码

    #include <algorithm>
    #include <iostream>
    #include <map>
    #include <stdio.h>
    #include <string.h>
    #define pb push_back
    typedef long long ll;
    using namespace std;
    const int mod = 1e9 + 7;
    const int N = 2e5 + 10;
    
    int fa[N];
    map<int, map<int, int>> mp;
    int find(int x)
    {
        if (fa[x] == x)
            return x;
        return fa[x] = find(fa[x]);
    }
    int c[N];
    int main()
    {
        int n, q;
        scanf("%d%d", &n, &q);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &c[i]);
            mp[i][c[i]] = 1;
            fa[i] = i;
        }
        while (q--) {
            int op, x, y;
            scanf("%d%d%d", &op, &x, &y);
            if (op == 1) {
                int xx = find(x), yy = find(y);
                if (xx != yy) {
                    if (mp[xx].size() > mp[yy].size()) {
                        swap(xx, yy);
                    }
                    fa[xx] = yy;
                    for (map<int, int>::iterator it = mp[xx].begin(); it != mp[xx].end(); ++it) {
                        mp[yy][it->first] += it->second;
                    }
                }
            } else {
                int xx = find(x);
                map<int, int>::iterator pos = mp[xx].find(y);
                if (pos != mp[xx].end())
                    printf("%d\n", mp[xx][y]);
                else
                    printf("0\n");
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    cs224n word2vec
    背包问题
    动态规划二
    动态规划
    递推求解
    Tmux 使用技巧
    LeetCode 75. Sort Colors
    LeetCode 18. 4Sum new
    LeetCode 148. Sort List
    LeetCode 147. Insertion Sort List
  • 原文地址:https://www.cnblogs.com/valk3/p/14000746.html
Copyright © 2020-2023  润新知