`
yzmduncan
  • 浏览: 326679 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

数据结构之——并查集

阅读更多

    用于不相交集合的数据结构——并查集。每个集合通过一个代表来识别,设x表示一个对象,我们希望支持一下操作:

    MakeSet(x):建立一个新的集合,其唯一成员就是x。

    Union(x,y):将包含x和y的动态集合(比如说Sx和Sy)合并为一个新的集合。

    FindSet(x):返回一个指针,指向x对象所属集合的代表(唯一)。

    一种加权合并的启发式策略。

    第一种启发:按秩合并(Union by rank),其思想是使包含较少结点的树根指向包含结点较多的树根。

    第二种启发:路径压缩(path compression),它非常简单而有效,路径压缩不改变结点的秩。

    当联合使用这两种策略时,最坏时间复杂度为O(4*m)。m为执行Union、findSet的次数,与对象个数n无关。

 

POJ1611:

题目大意:SARS(非典型肺炎)传播得非常厉害,其中最有效的办法是隔离那些患病、和患病者接触的人。现在有几个学习小组,每小组有几个学生,一个学生可能会参加多个小组。小组中只要有一个人得病,其余的都是嫌疑人。现在已知这些小组的人员,且0号学生已经患病,求一共有多少个嫌疑人。

分析:每个小组的人员属于同一个集合。在根节点记录每个集合的个数num[i],然后找到0所属的根节点,num[findSet(0)]即为所有的嫌疑人数。

#include <iostream>
const int MAX = 30001;
int n,m;
int p[MAX],rank[MAX];
int num[MAX];			//集合元素个数

int findSet(int x)
{
	if(x != p[x])
		p[x] = findSet(p[x]);
	return p[x];
}

void Union(int x,int y)
{
	if(x == y)
		return;
	if(rank[x] > rank[y])
	{
		p[y] = x;
		num[x] += num[y];
	}
	else
	{
		p[x] = y;
		if(rank[x] == rank[y])
			rank[y]++;
		num[y] +=num[x];
	}
}

int main()
{
	int i,j,k;
	int a,b;
	int s1,s2;
	while(true)
	{
		scanf("%d %d",&n,&m);
		if(n==0&&m==0) break;
		for(i = 0; i < n; i++)
		{
			p[i] = i;
			rank[i] = 0;
			num[i] = 1;
		}
		for(i = 0; i < m; i++)
		{
			scanf("%d",&k);
			scanf("%d",&a);
			for(j = 1; j < k; j++)
			{
				scanf("%d",&b);
				s1 = findSet(a);
				s2 = findSet(b);
				Union(s1,s2);
				a = i;
			}
		}
		i = findSet(0);
		printf("%d\n",num[i]);
	}
	return 0;
}

 

POJ1703,2924

    城市里面有两种帮派,警察想知道某两个人是否属于一个帮派。条件:给出a和b属于不同的帮派。

    用一个一维数组e[]保存敌对关系,例如e[a]=b,表示a的敌人是b,则在合并时:a与e[b]合并,b与e[a]合并。意思是a与b的敌人(a的朋友)合并。

#include <iostream>
const int MAX = 100001;
int p[MAX],rank[MAX],e[MAX];
//e[a] = b 表示a的敌人是b
int findSet(int x)
{
	if(p[x] != x)
		p[x] = findSet(p[x]);
	return p[x];
}

void Union(int x, int y)
{
	x = findSet(x);
	y = findSet(y);
	if(x == y)
		return;
	if(rank[x] > rank[y])
		p[y] = x;
	else
	{
		p[x] = y;
		if(rank[x] == rank[y])
			rank[y]++;
	}
}

void initial(int n)
{
	for(int i = 1; i <= n; i++)
	{
		p[i] = i;
		rank[i] = 0;
		e[i] = 0;
	}
}

int main()
{
	int i,j;
	int cases;
	int n,m;
	char c;
	int a,b;
	scanf("%d",&cases);
	while(cases--)
	{
		scanf("%d %d",&n,&m);
		initial(n);
		for(i = 1; i <= m; i++)
		{
			getchar();
			scanf("%c %d %d",&c,&a,&b);
			if(c == 'A')
			{
				int fa = findSet(a);
				int fb = findSet(b);
				if(fa == fb)
					printf("In the same gang.\n");
				else
				{
					fb = findSet(e[b]);
					if(fa == fb)
						printf("In different gangs.\n");
					else
						printf("Not sure yet.\n");
				}
			}
			else //输入:a和b是敌人
			{
				int e1 = e[b];
				int e2 = e[a];
				if(e1 == 0)
					e[b] = a;
				else
					Union(a,e1);	//将a和b的敌人(即a的朋友)合并
				if(e2 == 0)
					e[a] = b;
				else
					Union(b,e2);	//将b和a的敌人(即b的朋友)合并
			}
		}
	}
	return 0;
}

 

POJ1182

    待续。。

 

 

分享到:
评论

相关推荐

    基础数据结构——作为软件开发人员必须掌握的基础

    目录 • 线性结构 • 二叉堆 • 并查集 • 哈希表 • 应用举例

    数据结构与算法之并查集(不相交集合)

    并查集是一种挺高效的数据结构。实现简单,只是所有元素统一遵从一个规律所以让办事情的效率高效起来。这篇文章主要介绍了数据结构与算法——并查集(不相交集合),需要的朋友可以参考下

    数据结构算法

    经典算法题每日演练——第十五题 并查集 经典算法题每日演练——第十四题 Prim算法 经典算法题每日演练——第十三题 赫夫曼树 经典算法题每日演练——第十二题 线段树 经典算法题每日演练——第十一题 Bitmap算法 ...

    大数据整理——数据集成.pdf

    ⼤数据整理 ⼤数据整理——数据集成 数据集成 数据集成 数据集成 1.背景: 背景: 因业务需要,事业单位内部普遍构建了多个异构的信息系统,这些信息系统中管理的数据源彼此独⽴、相互封闭,形成"信息孤岛"⽆法形成 ...

    AcWing算法基础课模板大全

    并查集 堆 Hash表 搜索与图论 —— 代码模板链接 常用代码模板3——搜索与图论 DFS与BFS 树与图的遍历:拓扑排序 最短路 最小生成树 二分图:染色法、匈牙利算法 数学知识 —— 代码模板链接 常用代码模板4——数学...

    C#全能速查宝典

    1.1.10 泛型——处理算法和数据结构 11 1.1.11 分部类——将一个类分成几部分 12 1.1.12 is操作符——检查变量是否为指定的类型 14 1.1.13 lock关键字——锁定 15 1.1.14 namespace关键字——定义命名空间 15 1.1.15...

    建议收藏算法基础课模板大全

    并查集 堆 Hash表 搜索与图论 —— 代码模板链接 常用代码模板3——搜索与图论 DFS与BFS 树与图的遍历:拓扑排序 最短路 最小生成树 二分图:染色法、匈牙利算法 数学知识 —— 代码模板链接 常用代码模板4——数学...

    大数据导论(1)——“大数据”相关概念、5V特征、数据类型.pdf

    ⾮结构化数据,是指不遵循统⼀的数据结构或模型的数据(如⽂本、图像、视频、⾳频等),不⽅便⽤⼆维逻辑表来表现。这部分数据 在企业数据中占⽐达,且增长速率更快。⾮结构化数据更难被计算机理解,不能直接被处理...

    大数据导论-6.1.2-熟悉大数据处理技术——大数据的技术架构.pptx

    (2)管理层:要支持在多源数据上做深层次的分析,大数据技术架构中需要一个管理平台,使结构化和非结构化数据管理融为一体,具备实时传送和查询、计算功能。本层既包括数据的存储和管理,也涉及数据的计算。并行化...

    数据结构、算法与应用:C++语言描述(原书第2版)第二部分

    6.5.4 并查集 第7章 数组和矩阵 7.1 数组 7.1.1 抽象数据类型 7.1.2 C++数组的索引 7.1.3 行主映射和列主映射 7.1.4 用数组的数组来描述 7.1.5 行主描述和列主描述 7.1.6 不规则二维数组 7.2 矩阵 7.2.1 定义和操作 ...

    《数据结构》试题库管理系统——计算机辅助教学 (1994年)

    《数据结构》试题库管理系统集数据库管理、试卷命题、评分、统计于一体,使试卷命题、阅卷、评分等一系列复杂的操作合理化、科学化、规范化。本试题库管理系统可完成试题的增加、删除、修改及模糊查询、动态条件组合...

    ACM 算法经典代码 数据结构经典代码

    2. 并查集扩展(friend_enemy) 98 3. 堆(binary) 98 4. 堆(mapped) 99 5. 矩形切割 99 6. 线段树 100 7. 线段树扩展 102 8. 线段树应用 105 9. 子段和 105 10. 子阵和 105 十三. 其他 106 1. 分数 106 2. 矩阵 108 3....

    精通windows server 2008 命令行与powershell 电子书PDF单文件完整版

    1.2.5 tree——目录结构 43 1.2.6 type——浏览文本 44 1.2.7 verify——校验 45 1.2.8 verifier——驱动程序检验 46 1.2.9 where——位置 47 第2章 磁盘管理 49 2.1 磁盘分区与格式化 49 2.1.1 硬盘分区 49 2.1.2 ...

    Excel公式与函数大辞典.宋翔(带书签高清文字版).pdf

    5.5.3 FINDB——以字节为单位并区分大小写地查找指定字符的位置 187 5.5.4 REPLACE——以字符为单位根据指定位置进行替换 188 5.5.5 REPLACEB——以字节为单位根据指定位置进行替换 189 5.5.6 SEARCH——以字符...

    精通windows server 2008 命令行与powershell电子书PDF版(第一卷)

    3.4.4 graftabl——启用扩展字符集 119 3.4.5 mode——系统设置 121 3.4.6 path——路径 125 3.4.7 reg——修改注册表子项 125 3.4.8 regedit——注册表编辑器 132 3.4.9 regsvr32——将dll文件注册为命令 132 ...

    精通windows server 2008 命令行与powershell 电子书PDF版(第四卷)

    3.4.4 graftabl——启用扩展字符集 119 3.4.5 mode——系统设置 121 3.4.6 path——路径 125 3.4.7 reg——修改注册表子项 125 3.4.8 regedit——注册表编辑器 132 3.4.9 regsvr32——将dll文件注册为命令 132 ...

    精通windows server 2008 命令行与powershell电子书PDF版(第三卷)

    3.4.4 graftabl——启用扩展字符集 119 3.4.5 mode——系统设置 121 3.4.6 path——路径 125 3.4.7 reg——修改注册表子项 125 3.4.8 regedit——注册表编辑器 132 3.4.9 regsvr32——将dll文件注册为命令 132 ...

    精通windows server 2008 命令行与powershell电子书PDF版(第二卷)

    3.4.4 graftabl——启用扩展字符集 119 3.4.5 mode——系统设置 121 3.4.6 path——路径 125 3.4.7 reg——修改注册表子项 125 3.4.8 regedit——注册表编辑器 132 3.4.9 regsvr32——将dll文件注册为命令 132 ...

    大数据概述——精选推荐.pdf

    图计算 针对⼤规模图结构数据的处 理 Pregel、GraphX、Giraph、PowerGraph、Hama、GoldenOrb等 查询分析计 算 ⼤规模数据的存储管理和查 询分析 Dremel、Hive、Cassandra、Impala等 七,⼤数据产业: ⼤数据产业是指...

Global site tag (gtag.js) - Google Analytics