并查集 堆排序 模拟堆(9/10)

并查集模板

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

#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;
}

 模拟堆

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
const int N = 100010;
int h[N]; int hp[N], ph[N];
int n; int siz ;
void swap_heap(int a,int b)
{
    swap(ph[hp[a]], ph[hp[b]]);
    swap(hp[a], hp[b]);
    swap(h[a],h[b]);
}
void up(int u)
{
    while (u / 2 && h[u / 2] > h[u])
    {
        swap_heap(u, u / 2);
        u /= 2;
    }
}

void down(int u)
{
    int t = u;
    if (h[u * 2] < h[t] && u * 2 <= siz) t = u * 2;//注意这段代码
    if (h[u * 2 + 1] < h[t] && u * 2 + 1 <= siz) t = u * 2 + 1;
    if (t != u) {
        swap_heap(u,t);
        down(t);
    }
}
int main()
{
    cin >> n; int idx=0;
    while (n--)
    {
         char op[5]; scanf("%s", op);int k,x;
        if (!strcmp(op, "I")) {
            scanf("%d", &x);
            siz++;idx++;
            ph[idx] = siz; hp[siz] = idx;
            h[siz] = x;
            up(siz);
        }
        else if (!strcmp(op, "PM")) printf("%d\n", h[1]);
        else if (!strcmp(op, "D")) {
            scanf("%d", &k);
            k = ph[k]; swap_heap(k, siz);
            siz--;
            up(k); down(k);
        }
        else if(!strcmp(op, "DM")){
           swap_heap(1,siz);
           siz--;
           down(1);
        }
        else{
            scanf("%d%d", &k, &x);
            k = ph[k]; h[k] = x;
            up(k); down(k);
        }
    }
    return 0;
}

 

posted @ 2023-09-10 23:29  敲代码的6  阅读(15)  评论(0)    收藏  举报