并查集 堆排序 (9/10)

发布时间 2023-09-10 23:31:46作者: 敲代码的6

并查集模板

 注意查找到后查找的节点直接连接根节点

#include<iostream>
using namespace std;
const int N = 100010;
int p[N];

//关键记住find函数
int find(int a) { if (p[a] != a) p[a] = find(p[a]);//不等于根节点就往头结点走,并且等于 return p[a]; } int main() { int m, n; scanf("%d%d", &m, &n); for (int i = 1; i <= m; i++) p[i] = i;//每个节点都赋值为根节点 while (n--) { char c; cin >> c; int x, y; if (c == 'M') { scanf("%d%d", &x, &y); p[find(x)] = find(y);//让右边作为左边的根节点 } else { scanf("%d%d", &x, &y); if (find(x) == find(y))printf("Yes\n"); else printf("No\n"); } } return 0; }

 

堆排序

 

#include<iostream>
using namespace std;
const int N = 1000010;
int a[N];
int n, m; int siz;
void down(int u)
{
    int t = u;//注意下面判断时用u,不要用t,因为t会改变,而后面的t是比较小的数,用小的比较
    if (a[u * 2] < a[t] && u * 2 <= siz) t = u * 2;
    if (a[u * 2 + 1] < a[t] && u * 2 + 1 <= siz) t = u * 2 + 1;
    if (t != u) {
        swap(a[t], a[u]);
        down(t);
    }
}
int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    siz = n;
    for (int i = n / 2; i; i--) down(i);
    while (m--){
        printf("%d ", a[1]);
        a[1] = a[siz];
        siz--;//先减1,再down
        down(1);
    }
    return 0;
}