首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【小码匠自习室】12月份划重点:并查集

【小码匠自习室】12月份划重点:并查集

作者头像
小码匠
发布2022-12-06 11:02:59
发布2022-12-06 11:02:59
2770
举报

12月划重点: 3个数据结构

  • 并查集
  • 线段树
  • 树状数组

开工

有老码农操刀帮我整理资料,省掉了很多搜集资料时间,老码农继续努力哟。。。

今天下午先是看视频,然后看算法训练营的示例,看完示例,自然就要打一个板子。

题目:P3367 【模板】并查集

  • 地址:https://www.luogu.com.cn/problem/P3367
  • 初版代码
代码语言:javascript
复制
#include <bits/stdc++.h>

using namespace std;
#define endl '\n';

vector<int> fa(10005); //先初始化一个大数组

int Find(int a) {
    if (a != fa[a]) { //如果a的父节点不是本身,就往前找到其祖宗节点
        fa[a] = Find(fa[a]); //往回返的时候把路上遍历过的所有节点更新为祖宗节点
    }
    return fa[a];
}

void Union(int x, int y) {
    int a = Find(x);
    int b = Find(y); //找到两个数的祖宗节点
    if (a != b) {
        fa[b] = a; //合并时只改其祖宗节点
    }
}

void find_union(int x, int y) { //需要输出值时使用的,和上面原理一样
    int a = Find(x);
    int b = Find(y);
    if (a == b) {
        cout << "Y" << endl;
    } else {
        cout << "N" << endl;
    }
}

void best_coder() {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) {
        fa[i] = i; //要记得现将每个节点的祖宗节点更新为本身
    }
    for (int i = 0; i < m; ++i) {
        int a, b, c;
        cin >> a >> b >> c;
        if (a == 1) { //根据题目要求调用不同的函数就OK啦
            Union(b, c);
        } else {
            find_union(b, c);
        }
    }
}

void happy_coder() {
}

int main() {
    // 提升cin、cout效率
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    // 小码匠
    best_coder();

    // 最优解
    // happy_coder();

    // 返回
    return 0;
}

上面的初版代码一次AC,老码农看后显然很不满意,又拽给我几个示例代码,还美其名曰:让我写个漂亮的板子出来。

修改后的板子代码

代码语言:javascript
复制
#include <bits/stdc++.h>

using namespace std;
#define endl '\n';

struct UF {
    vector<int> fa;

    UF(int n) : {
        fa(n) {}
    }
    
    void initialize (int n) {
        for (int i = 1; i <= n; ++i) {
            fa[i] = i; //要记得先将每个节点的祖宗节点更新为本身
        }
    }

    int Find(int a) {
        if (a != fa[a]) { //如果a的父节点不是本身,就往前找到其祖宗节点
            fa[a] = Find(fa[a]); //往回返的时候把路上遍历过的所有节点更新为祖宗节点
        }
        return fa[a];
    }

    void Union(int x, int y) {
        int a = Find(x);
        int b = Find(y); //找到两个数的祖宗节点
        if (a != b) {
            fa[b] = a; //合并时只改其祖宗节点
        }
    }

    bool is_same(int x, int y) { //判断两个数在不在一个集合里
        return Find(x) == Find(y);
    }
};

void best_coder() {
    int n, m;
    cin >> n >> m;
    UF uf(n);
    uf.initialize(n);
    for (int i = 0; i < m; ++i) {
        int a, b, c;
        cin >> a >> b >> c;
        if (a == 1) { //根据题目要求调用不同的函数就OK啦
            uf.Union(b, c);
        } else {
            if (uf.is_same(b, c)) {
                cout << "Y" << endl;
            } else {
                cout << "N" << endl;
            }
        }
    }
}

void happy_coder() {
}

int main() {
    // 提升cin、cout效率
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    // 小码匠
    best_coder();

    // 最优解
    // happy_coder();

    // 返回
    return 0;
}

没完没了

欺负小孩没商量,写完模板题,老码农随手又拽给我8道题,美其名曰:要好好巩固所学知识。我有选择的权力吗????

下周又没好日子过了。

  • P2256 一中校运会之百米跑
  • P3144 [USACO16OPEN]Closing the Farm S
  • P2814 家谱
  • P6121 [USACO16OPEN]Closing the Farm G
  • CF103B Cthulhu
  • ABC157-D
  • ABC177-D
  • CF356A Knight Tournament
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-12-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小码匠和老码农 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 12月划重点: 3个数据结构
    • 开工
    • 题目:P3367 【模板】并查集
    • 没完没了
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档