并查集是解决集合之间关系的一种很好理解的数据结构
就相当于将一个个集合合并成一棵树
然后将每个节点都只想根节点
主要两个操作是join(a,b);将两个节点合并在一起
find(x);查找x的根节点
时间复杂度为树的高度O(h)
如果数据特别没节操就会卡成一条链 就成O(n)的时间复杂度了
优化有两种方法 其中路径压缩是最常见的
因为树的形态完全不重要 所以将树的节点都连在同一层上 时间复杂度就成O(1)了;
给一个介绍很形象生动的博客http://blog.csdn.net/ljfbest/article/details/6642769
1 # include<cstdio> 2 # include<cstring> 3 const int maxn=1005; 4 int n,m; 5 int pre[maxn];//每一个节点记录上一级的位置 6 /*int find(int x){ 7 int r=x; 8 while(r!=pre[r])r=pre[r]; //并查集最简单的查找 9 return r; 10 } 11 */ 12 int find_dfs(int x){ 13 if(x!=pre[x])pre[x]=find_dfs(pre[x]);//并查集查找递归版 ,不适用大数据 14 return pre[x]; 15 } 16 int find_best(int x){ 17 int r,j,k; //常用简单的查找方法 18 int r=x; 19 while(r!=pre[r])r=pre[r]; 20 k=x; 21 while(k!=r){j=pre[k];pre[k]=r;k=j;} 22 return r; 23 } //路径压缩的两种方法 24 void join(int x,int y){ 25 int fx=find(x); 26 int fy=find(y); //分别找到两个节点的最大父亲 27 if(fx!=fy)pre[fx]=fy; //判别是否在同一支点里,如果不是就脸上 28 } 29 int main(){ 30 while(scanf("%d%d",&n,&m)!=EOF){ 31 for(i=1;i<=n;i++)pre[i]=i;//标记每个点都是独立的 32 33 } 34 return 0; 35 }
时间: 2025-01-08 18:52:26