zoukankan      html  css  js  c++  java
  • ACwing(基础)--- 并查集、堆

    并查集

    • union:将两个集合合并
    • query:询问两个元素是否在一个集合当中

    基本原理:每个集合用一棵树来表示。树根的编号就是整个集合的编号。每个节点存储它的父节点,p[x]表示x的父节点

    问题一:如何判断树根:if(p[x] == x)

    问题二:如何求x的集合编号:while(p[x] != x) x = p[x];

    优化:路径压缩

    int find(int x) //返回x的祖宗节点+路径压缩
    {
        if(p[x] != x) p[x]=find(p[x]);
        return p[x];
    }
    

    问题三:如何合并两个集合:px是x的集合编号,py是y集合编号。p[x]=y

    p[find(a)] = find(b);//合并两个集合
    

    注意:记得初始化数组

    //初始化
    void init()
    {
      for(int i=1;i<=n;i++) p[i]=i;
    }
    

    • 1、插入一个数
    heap[++size] = x;
    up(size);
    
    • 2、求集合当中的最小值
    heap[1];
    
    • 3、删除最小值
    heap[1] = heap[size];
    size--;
    down(1);
    
    • 4、删除任意一个元素
    heap[k] = heap[size];
    size--;
    down(k);up(k);
    
    • 5、修改任意一个元素
    heap[k] = x;
    down(k);up(k);
    

    线性时间复杂度的算法将该堆调整为最小堆(小根堆)

    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    const int N = 1e3+10;
    
    int n,m;
    int heap[N],size;
    
    void down(int u) {
    	int t=u;
    	if(u*2<=size&&heap[u*2]<heap[t]) t = u*2;
    	if(u*2+1 <= size && heap[u*2+1]<heap[t]) t=u*2+1;
    	if(t != u) {
    		swap(heap[t],heap[u]);
    		down(t);
    	}
    }
    int main() {
    	cin>>n>>m;
    	for(int i=1; i<=n; i++) cin>>heap[i];
    	size = n;
    	for(int i=n/2; i; i--) {
    		down(i);
    	}
    }
    

    逐个按顺序插入到初始为空的最小堆(小根堆)

    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    const int N = 1e3+10;
    
    int n,m;
    int heap[N],size;
    
    void up(int u) {
    	while(u/2 && heap[u/2]>heap[u]) {
    		swap(heap[u/2],heap[u]);
    		u/=2;
    	}
    }
    int main() {
    	cin>>n>>m;
    	int x;
    	for(int i=1; i<=n; i++) cin>>x,heap[++size]=x,up(size);
            //输出h[i]到根节点的路径
    	for(int i=0; i<m; i++) {
    		int j;
    		cin>>j;
    		cout<<heap[j];
    		while(j>1) {
    			j/=2;
    			cout<<" "<<heap[j];
    		}
    		puts("");
    	}
    }
    
  • 相关阅读:
    文件字符输入输出流
    ava.io.InputStream & java.io.FileInputStream
    java.io.OutputStream & java.io.FileOutputStream
    java.lang.String & java.lang.StringBuilder
    文件过滤器
    递归
    原生camera应用 保存设置界面参数方法
    android 获取调用camera service的进程
    linux 查找,替换 常用命令
    将一个项目修改记录提交另外一个项目-> patch获取提交记录,repo 提交代码
  • 原文地址:https://www.cnblogs.com/bingers/p/13503860.html
Copyright © 2011-2022 走看看