- 浏览: 1656353 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (405)
- C/C++ (16)
- Linux (60)
- Algorithm (41)
- ACM (8)
- Ruby (39)
- Ruby on Rails (6)
- FP (2)
- Java SE (39)
- Java EE (6)
- Spring (11)
- Hibernate (1)
- Struts (1)
- Ajax (5)
- php (2)
- Data/Web Mining (20)
- Search Engine (19)
- NLP (2)
- Machine Learning (23)
- R (0)
- Database (10)
- Data Structure (6)
- Design Pattern (16)
- Hadoop (2)
- Browser (0)
- Firefox plugin/XPCOM (8)
- Eclise development (5)
- Architecture (1)
- Server (1)
- Cache (6)
- Code Generation (3)
- Open Source Tool (5)
- Develope Tools (5)
- 读书笔记 (7)
- 备忘 (4)
- 情感 (4)
- Others (20)
- python (0)
最新评论
-
532870393:
请问下,这本书是基于Hadoop1还是Hadoop2?
Hadoop in Action简单笔记(一) -
dongbiying:
不懂呀。。
十大常用数据结构 -
bing_it:
...
使用Spring MVC HandlerExceptionResolver处理异常 -
一别梦心:
按照上面的执行,文件确实是更新了,但是还是找不到kernel, ...
virtualbox 4.08安装虚机Ubuntu11.04增强功能失败解决方法 -
dsjt:
楼主spring 什么版本,我的3.1 ,xml中配置 < ...
使用Spring MVC HandlerExceptionResolver处理异常
最近学习了并查集、线段树、树状数组以及RMQ(Range Minimum Query)这几种关于快速查找
的数据结构和算法,并做了一些ACM的题目巩固了一下。准备写一下总结。
本次总结一下并查集:
并查集对解决不相交集合的合并查找操作非常有效,主要提供了一下几个方法:
make_set(x) 把每一个元素初始化为一个集合
find_set(x) 查找一个元素所在的集合
union_set(x,y) 合并x,y所在的两个集合
空间复杂度为O(N),建立一个集合的时间复杂度为O(1),N次合并M查找的时间复杂度为O(M Alpha(N)),
这里Alpha是Ackerman函数的某个反函数,在很大的范围内这个函数的值可以看成是不大于4的,所以并
查集的操作可以看作是线性的。
并查集针对不同的问题有两种不同的实现:
第一种:
make_set(x)的时候parent[x] = x,也就是根的parent指向自己,以此来判断这个元素是否为根元素,
rank值记录树的高度,合并的时候尽量让小的合并到大的集合上,这样可以减少数的高度。
代码如下:
第二种:
make_set的时候把parent[x] = -1,根节点parent记录了该集合元素个数
的相反数,所以这种方法很适合想知道某个元素所在的集合的个数的情况。
以下是这两种并查集的两道ACM应用,可以巩固一下学习的知识:
poj2524 http://acm.pku.edu.cn/JudgeOnline/problem?id=2524
这道题目的主要意思是:n个大学生,指出m对宗教信仰相同的学生,然后让你估算这n个学生中最多
有多少种宗教信仰。
这道题很简单,把宗教数初始化为学生数n,对给出的每对大学生i,j,如果他们在不同的集合,那么
就合并,然后宗教的数量减一
以下是AC的代码:
poj 1611 The Suspects http://acm.pku.edu.cn/JudgeOnline/problem?id=1611
这道题的意思是有一种传染病SARS,学生有很多的groups,如果groups的一个学生是疑似患者Suspect,
则整个组的其他人都是Suspects,但一个人可能属于不同的组,初始0是suspect,问学生中有多少个
Suspects.
这个题目很简单,把同一组的人进行合并,然后查找一个0元素所在集合元素的个数,由于要统计一个
集合元素的个数,所以使用第二种构造并查集的方法。
AC的代码:
其他来自fandy_wang总结中提供的一些相关题目:
POJ 1182 食物链
并查集的拓展注意: 只有一组数据;
要充分利用题意所给条件:有三类动物A,B,C,这三类动物的食物链
构成了有趣的环形。A吃B, B吃C,C吃A。也就是说:只有三个group
POJ 2492 A Bug's Life 并查集的拓展
法一:深度优先遍历
每次遍历记录下该点是男还是女,只有:男-〉女,女-〉男满足,否则,找到同性恋,结束程序。
法二:二分图匹配
法三:并查集的拓展:和1182很像,只不过这里就有两组,而1182是三组,1611无限制
POJ 1861 Network == zju_1542 并查集+自定义排序+贪心求"最小生成树"
答案不唯一,不过在ZOJ上用QSORT()和SORT()都能过,在POJ上只有SORT()才能过...
POJ 1703 Find them, Catch them 并查集的拓展
这个和POJ 2492 A Bug's Life很像,就是把代码稍微修改了一下就AC了!
注意:And of course, at least one of them belongs to Gang Dragon, and the same for Gang Snake. 就是说只有两个组。
POJ 2236 Wireless Network 并查集的应用
需要注意的地方:1、并查集;2、N的范围,可以等于1001;3、从N+1行开始,第一个输入的可以是字符串。
POJ 1988 Cube Stacking 并查集很好的应用
1、与 银河英雄传说==NOI2002 Galaxy一样;2、增加了一个数组behind[x],记录战舰x在列中的相对位置;3、详细解题报告见银河英雄传说。
JOJ 1905 Freckles == POJ 2560 最小生成树
法一:Prim算法;法二:并查集实现Kruskar算法求最小生成树
JOJ 1966 Super Market III == PKU 1456 Supermarket 带限制的作业排序问题(贪心+并查集)
提高题目:
POJ 2912 Rochambeau
POJ 1733 Parity game
POJ 1308 Is It A Tree?
的数据结构和算法,并做了一些ACM的题目巩固了一下。准备写一下总结。
本次总结一下并查集:
并查集对解决不相交集合的合并查找操作非常有效,主要提供了一下几个方法:
make_set(x) 把每一个元素初始化为一个集合
find_set(x) 查找一个元素所在的集合
union_set(x,y) 合并x,y所在的两个集合
空间复杂度为O(N),建立一个集合的时间复杂度为O(1),N次合并M查找的时间复杂度为O(M Alpha(N)),
这里Alpha是Ackerman函数的某个反函数,在很大的范围内这个函数的值可以看成是不大于4的,所以并
查集的操作可以看作是线性的。
并查集针对不同的问题有两种不同的实现:
第一种:
make_set(x)的时候parent[x] = x,也就是根的parent指向自己,以此来判断这个元素是否为根元素,
rank值记录树的高度,合并的时候尽量让小的合并到大的集合上,这样可以减少数的高度。
代码如下:
int parent[50001]; int rank[50001]; void make_set(int x){ parent[x] = x; rank[x] = 0; } //查找的时候,进行路径压缩parent[x] = find_set(parent[x]), //把查找路径上的结点都指向跟结点,减小树的高度 int find_set(int x){ if(x != parent[x]) parent[x] = find_set(parent[x]); return parent[x]; } void union_set(int x,int y){ int r1 = find_set(x); int r2 = find_set(y); if(r1 == r2) return;//如果两个元素在相同的集合中,直接retun; if(rank[r1] < rank[r2]//把rank值较小的集合合并到达的集合中 parent[r2] = r1; else{ if(rank[r1] == rank[r2])//两个rank值相等的树合并后rank要增加一 rank[r2] += 1; parent[r1] = r2; } }
第二种:
make_set的时候把parent[x] = -1,根节点parent记录了该集合元素个数
的相反数,所以这种方法很适合想知道某个元素所在的集合的个数的情况。
int parent[30001]; void make_set(int x){ parent[x] = -1; } int find_set(int x){ int p = x; while(parent[p] > 0) p = parent[p];//找到跟结点 while(x != p){//查找并压缩路径,让查找路径上的每一个x的parent[x] = p,p为根节点 int temp = parent[x]; parent[x] = p; x = temp; } return x; } void union_set(int x,int y){ int r1 = find_set(x); int r2 = find_set(y); if(r1 == r2) return; if(parent[r1] < parent[r2]){//集合小的合并到集合大的上,并更新集合元素个数的计数 parent[r1] += parent[r2]; parent[r2] = r1; }else{ parent[r2] += parent[r1]; parent[r1] = r2; } }
以下是这两种并查集的两道ACM应用,可以巩固一下学习的知识:
poj2524 http://acm.pku.edu.cn/JudgeOnline/problem?id=2524
这道题目的主要意思是:n个大学生,指出m对宗教信仰相同的学生,然后让你估算这n个学生中最多
有多少种宗教信仰。
这道题很简单,把宗教数初始化为学生数n,对给出的每对大学生i,j,如果他们在不同的集合,那么
就合并,然后宗教的数量减一
以下是AC的代码:
#include<iostream> using namespace std; int parent[50001]; int rank[50001]; void make_set(int x){ parent[x] = x; rank[x] = 0; } int find_set(int x){ if(x != parent[x]) parent[x] = find_set(parent[x]); return parent[x]; } void union_set(int x,int y){ int r1 = find_set(x); int r2 = find_set(y); if(r1 == r2) return; if(rank[r1] < rank[r2]) parent[r2] = r1; else{ if(rank[r1] == rank[r2]) rank[r2] += 1; parent[r1] = r2; } } int main(){ int m,n; int ncases = 0; int i = 0; while(cin >> n >> m, n){ int a,b; ++ncases; for(i = 0; i < n; i++){ make_set(i); } for(i = 0; i < m; i++){ cin >> a >> b; int x = find_set(a); int y = find_set(b); if(x != y){//不同的集合,合并并减一 n--; union_set(x,y); } } cout << "Case " << ncases << ": " << n << endl; } return 0; }
poj 1611 The Suspects http://acm.pku.edu.cn/JudgeOnline/problem?id=1611
这道题的意思是有一种传染病SARS,学生有很多的groups,如果groups的一个学生是疑似患者Suspect,
则整个组的其他人都是Suspects,但一个人可能属于不同的组,初始0是suspect,问学生中有多少个
Suspects.
这个题目很简单,把同一组的人进行合并,然后查找一个0元素所在集合元素的个数,由于要统计一个
集合元素的个数,所以使用第二种构造并查集的方法。
AC的代码:
#include<iostream> using namespace std; int parent[30001]; void make_set(int x){ parent[x] = -1; } int find_set(int x){ int p = x; while(parent[p] > 0) p = parent[p]; while(x != p){ int temp = parent[x]; parent[x] = p; x = temp; } return x; } void union_set(int x,int y){ int r1 = find_set(x); int r2 = find_set(y); if(r1 == r2) return; if(parent[r1] < parent[r2]){ parent[r1] += parent[r2]; parent[r2] = r1; }else{ parent[r2] += parent[r1]; parent[r1] = r2; } } int main(){ int n,m,i = 0; while(cin >> n >> m, n){ for(i = 0; i < n; i++){ make_set(i); } for(i = 0; i < m; i++){ int k; cin >> k; int first_s,s; cin >> first_s; for(int j = 1; j < k; j++){ cin >> s; union_set(first_s,s); } } cout << -parent[find_set(0)] << endl; } return 0; }
其他来自fandy_wang总结中提供的一些相关题目:
POJ 1182 食物链
并查集的拓展注意: 只有一组数据;
要充分利用题意所给条件:有三类动物A,B,C,这三类动物的食物链
构成了有趣的环形。A吃B, B吃C,C吃A。也就是说:只有三个group
POJ 2492 A Bug's Life 并查集的拓展
法一:深度优先遍历
每次遍历记录下该点是男还是女,只有:男-〉女,女-〉男满足,否则,找到同性恋,结束程序。
法二:二分图匹配
法三:并查集的拓展:和1182很像,只不过这里就有两组,而1182是三组,1611无限制
POJ 1861 Network == zju_1542 并查集+自定义排序+贪心求"最小生成树"
答案不唯一,不过在ZOJ上用QSORT()和SORT()都能过,在POJ上只有SORT()才能过...
POJ 1703 Find them, Catch them 并查集的拓展
这个和POJ 2492 A Bug's Life很像,就是把代码稍微修改了一下就AC了!
注意:And of course, at least one of them belongs to Gang Dragon, and the same for Gang Snake. 就是说只有两个组。
POJ 2236 Wireless Network 并查集的应用
需要注意的地方:1、并查集;2、N的范围,可以等于1001;3、从N+1行开始,第一个输入的可以是字符串。
POJ 1988 Cube Stacking 并查集很好的应用
1、与 银河英雄传说==NOI2002 Galaxy一样;2、增加了一个数组behind[x],记录战舰x在列中的相对位置;3、详细解题报告见银河英雄传说。
JOJ 1905 Freckles == POJ 2560 最小生成树
法一:Prim算法;法二:并查集实现Kruskar算法求最小生成树
JOJ 1966 Super Market III == PKU 1456 Supermarket 带限制的作业排序问题(贪心+并查集)
提高题目:
POJ 2912 Rochambeau
POJ 1733 Parity game
POJ 1308 Is It A Tree?
发表评论
-
二分查找之变型题目
2010-10-24 12:40 2163二分查找算法在各个公司的笔试面试题大量出现,通常不是简单一眼就 ... -
一道笔试题(创新工厂)解法
2010-10-21 17:44 1862一个帖子http://www.iteye.com/topic/ ... -
[zz]大数据量,海量数据 处理方法总结
2010-08-27 22:24 2276大数据量的问题是很多面试笔试中经常出现的问题,比如baidu ... -
Trie and suffix array
2010-04-13 20:54 1933字典数Trie和后缀数组suffix array是处理字符串操 ... -
金币问题
2009-11-09 08:41 2031今年某公司的笔试题: 一个矩阵地图,每一个元素值代表金币数, ... -
楼梯问题
2009-11-09 08:19 1581hl给我的几道某公司的算法题: 1、 有个 100 级的 ... -
一道考察模拟乘法的题目
2009-11-07 22:37 1426今天hl和我讨论一道题目: 写道 整形数组如a={1,4, ... -
链表归并
2009-11-07 21:40 1044以前gx同学问的某某公司的笔试题,写一下练练(纯手写,没编译过 ... -
找出出现次数超过一半的数字
2009-11-07 21:23 1893hl同学问我一道这个题,想了一种方法,感觉还是不错的,只扫描一 ... -
有道难题以超低分晋级
2009-06-10 11:36 1576有道难题比赛居然晋级了,可以领到一个t-shirt。 -
逆序数/逆序数对
2009-06-09 23:17 3794逆序数是个常遇到的问题,主要有两种解法: O(n^2)的方法: ... -
有道难题topcoder
2009-05-31 23:55 2467今天做了有道topcoder的题目,也是第一次在topcode ... -
百度之星第一场题目
2009-05-31 00:03 3664由于不符合参赛条件,未能参加百度之星,看了题目还挺有意思,把题 ... -
一个对字符串很好的Hash函数ELFHHash
2009-05-03 21:41 2287#include<stdio.h> #defin ... -
最大流Ford-Fulkerson算法
2009-04-22 17:33 9703算法导论对最大流算法有很详细的介绍,今天实现了最大流Ford- ... -
大数/高精度加减乘除取模[收藏]
2009-04-16 19:38 5080#include <iostream> #i ... -
带重复数字的全排列
2009-04-16 18:58 3905上次gx同学问我一道又重复数字的全排列的问题,我当时用set保 ... -
差分约束系统
2009-04-15 16:00 3760(本文假设读者已经有以下知识:最短路径的基本性质、Bellma ... -
二分图匹配
2009-04-15 15:40 3735二分图最大匹配的匈牙利算法 二分图是这样一个图,它的顶点可以分 ... -
线段树
2009-03-24 10:58 1690把问题简化一下: 在自然数,且所有的数不大于30000的 ...
相关推荐
《高级数据结构》是一本由Peter Brass编写,剑桥大学出版社出版的专业书籍。本书旨在为读者提供深入学习数据结构的机会,特别是那些对于计算机科学有着较高追求的学生或专业人士。本书不仅涵盖了基础数据结构,还...
数据结构是计算机科学中的核心课程之一,它研究如何在计算机中高效地组织和管理数据,以便进行快速查找、插入和删除等操作。严蔚敏教授的《数据结构》一书,是中国计算机教育的经典教材,其C语言版本更是深受广大...
1. **数据预处理**:对空间对象进行分割和编码,生成适合索引的数据结构。 2. **LOD构建**:创建多级细节表示,每一级对应不同的空间分辨率。 3. **索引构建**:基于LOD构建高效的索引结构,如B树、R树或四叉树等。 ...
在计算机科学中,"算法中最小K元素的选择问题"是一个重要的数据结构和算法主题,它涉及到从一个无序或有序的数组中找到第K小(或大)的元素。这个问题在各种应用场景中都有广泛的应用,比如数据库查询优化、排序算法...
并查集是一种支持快速查找和合并操作的数据结构,对于Kruskal算法来说,其主要作用在于检测环路。并查集的操作包括: - **Find(x)**:返回顶点x所在的集合的代表元素,用于确定顶点x和另一个顶点y是否在同一集合中...
《挑战程序设计竞赛2》是一本专注于算法和数据结构的编程竞赛指南,旨在帮助参赛者提升在编程竞赛中的表现。这本书结合了理论与实践,深入浅出地讲解了各种常用的算法和数据结构,并且提供了相应的源码供读者学习和...
在查询操作的具体实现中,以选择操作和连接操作为例,有多种算法可供选择: #### 选择操作的实现 1. **全表扫描**:当查询条件较为简单或没有适用的索引时,DBMS会遍历整个表的每一行,检查是否满足查询条件。虽然...
17. 数据结构:包括ST表、堆、树状数组、线段树、Trie树、并查集、平衡树等高级数据结构。 18. 计算几何:包括基础计算和基本位置关系判定、概率论、博弈论等计算几何知识点。 19. 字符串:包括AC自动机、拓展KMP、...
根据查询条件,我们可以对整个数据集进行快速查找。 结果展示通常涉及数据可视化。MATLAB的绘图功能强大,可以创建表格、图表或数据显示窗口来呈现查询结果。例如,我们可以使用`uitable`显示一个包含查询结果的...
JSI的核心思想是通过数据结构和算法将空间数据组织起来,以便在进行空间查询时能够减少搜索范围,提高性能。通常,这种索引会基于某种特定的数据结构,如R树、quadtree或B树等,这些数据结构设计的目的就是处理多维...
PGM索引是一种创新的学习数据结构,专门设计用于在大规模数据集,特别是包含数十亿项目的数组中执行高效、节省空间的查找、前驱查询、范围搜索和更新操作。这一技术结合了机器学习与传统数据库索引方法,为处理...
在易语言中,模块是一个可重用的代码单元,它可以封装一系列相关的函数、过程或者数据结构,方便开发者在不同的程序中调用。新查询快捷方式模块可能包含了针对数据库查询、字符串查找、数组搜索等常见查询任务的高效...
【C/C++快件管理系统】是一个使用C或C++编程语言实现的软件系统,它主要用于模拟和管理快递行业的日常操作。...尽管描述中提到代码可供参考,但真正理解和掌握这些知识点,还需要亲自实践和研究源码。
排序是计算机科学中的核心概念,有多种算法可供选择,比如冒泡排序、选择排序、插入排序和快速排序等。学生在项目中不仅需要实现至少一种排序算法,还应理解其基本思想和优缺点。例如,冒泡排序虽然简单易懂,但在...
对结构化数据的搜索,例如使用SQL查询数据库,或者在Windows中基于文件名、类型、修改时间等元数据进行搜索,通常较为高效,因为数据有明确的结构可供算法利用。然而,对非结构化数据的搜索,如在文档内容中查找特定...
2. **匹配引擎**:这是系统的核心,它使用解析器生成的数据结构来匹配目标字符串。对于DFA,匹配过程相对直观;而对于NFA,需要考虑回溯和分支的可能性。匹配引擎可能涉及到动态规划或贪心算法等复杂策略。 3. **...
2. **索引构建**:将处理后的文本转化为可供快速查询的索引结构,如倒排索引(Inverted Index)。 3. **查询处理**:接受用户输入的查询,对其进行解析和扩展,生成相应的查询表示。 4. **相关性计算**:根据查询...
模糊查询的核心在于实现一种搜索算法,该算法能在用户输入关键词时实时过滤并显示与之匹配的选项。常见的模糊查询算法有Levenshtein距离、Jaccard相似度、Tf-Idf等,但针对下拉框的简单模糊查询,一般使用更轻量级的...
它提供了一个交互式的环境,使用户能够快速地开发和测试算法,同时拥有丰富的图形显示能力,适合于处理大型数据集。 #### 二、IDL的优势 1. **高效的数据处理能力**:IDL能够快速处理大量的科学数据,尤其在图像和...
"Analyzer"一词通常与数据处理、逻辑推理和问题诊断相关联,而"Lib"是库(Library)的缩写,表明这是一组可供其他程序使用的函数或类。"Grapl"可能代表图形分析(Graph Analysis)或某种特定的数据结构,如图数据...