并查集小记
来源:互联网 发布:怎么看算法导论这本书 编辑:程序博客网 时间:2024/05/16 11:30
http://acm.hdu.edu.cn/showproblem.php?pid=1232
题目意思很简单,给出m条道路连通的情况,求n个城市连通至少还需要建多少条道路。应该算是赤裸裸的并查集,不过也可以用prim。借此道题目记录一下并查集的应用。
1,定义一个数组set[1...n],其中set[i]表示元素i所在的集合;用编号最小的元素记录所在集合;
//传进merge()的a,b即是set[x],set[y].
find(int x){return set[x];}merge(int a,int b){int x=min(a,b),y=max(a,b);for(int k=1;k<=n;k++)if(set[k]==y)set[k]=x;}
2, 1中的算法在进行合并操作时必须搜索所有的元素,复杂度较大,所以可以采用树结构。
定义数组set[1...n],set[i]= i,i表示本集合,并是集合对应的根;set[i]=j,j<>(不等于)i,则j 是i 的父节点。
find(int x){int r=x;while(r!=set[r])r=set[r];return r;}merge(int x,int y){if(x<y)set[y]=x;elseset[x]=y;}3,2中的查找在最坏情况下复杂度仍为O(n),为了避免最坏情况的出现,可以将深度小的树合并到深度大的树中。
find(int x){int r=x;while(r!=set[r])r=set[r];return r;}merge(int x,int y){if(height[x]==height[y]){height[x]=height[x]+1;set[y]=x;}else if(height[x]<height[y])set[x]=y;elseset[y]=x;}4,进一步优化---压缩路径
每次查找时,如果路径较长,则修改信息,以便下次查找时速度更快。step:1,找到根节点,2,修改查找路径上所有的节点,将它们都指向根节点。
find(int x){int r=x;while(r!=set[r])//循环结束,找到根节点r=set[r];int tmp=x,a;while(tmp!=r)//本循环修改查找路径中所有节点{a=set[tmp];set[tmp]=r;tmp=a;}return r;}最后附上1232代码:
#include<stdio.h>const int maxn = 1005;int set[maxn],height[maxn];void creat(int n){int i;for(i=1;i<=n;i++){set[i] = i;height[i] = 1;}}int find(int x){int r = x;while(r!=set[r])r = set[r];//寻找根节点int tmp = x,a;while(tmp!=r){a = set[tmp];set[tmp] = r;tmp = a;}//路径压缩return r;}void merge(int x,int y)//将深度小的树合并到深度大的树中{if(height[x] == height[y]){height[x]+=1;set[y] = x;}else if(height[x]<height[y])set[x] = y;elseset[y] = x;}int main(){int n,m,i,x,y,a,b;while(scanf("%d%d",&n,&m)!=EOF&&n){if(!m){printf("%d\n",n-1);continue;}creat(n);for(i=1;i<=m;i++){scanf("%d%d",&x,&y);a = find(x);b = find(y);merge(a,b);}int num = 0;for(i=1;i<=n;i++)if(set[i] == i)num++;printf("%d\n",num - 1);}return 0; }
- 并查集小记
- 并查集小记
- HDU3938 并查集 并查集
- 并查集(集并查)
- HDU1232 并查集<并>
- 并查集
- 数据结构-并查集
- 并查集
- 并查集!
- 并查集
- 并查集
- 并查集
- 并查集
- 并查集总结
- 并查集学习
- 并查集
- 并查集
- 并查集
- 报到
- Mysql 快速插入批量数据,从文件中导入数据
- SIGCOMM 2010 论文 paper list
- hibernate -----Could not instantiate cache implementation异常处理
- 【转】printf("%f/n",5)的输出结果为什么是0.000000
- 并查集小记
- 正确进行 windows 程序部署
- ehcache集群缓存配置说明
- VBA基础
- poj 2452
- Iphone开发笔记--Custom UITableVIewCell
- Android Push Notification
- 关于博客在教学中的应用课题研究的一点小资料(1)。。
- 字符串日期比较和时间差 and java时间操作函数汇总