
并查集
文章平均质量分 69
查尔斯欢
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
hdu3461
并查集题目,表示被题意折磨的好惨,百度了好几篇文章才看懂题目。 区间合并问题,初始化每个节点为一个区间,这样得到的所有解为26^n,之后每输入一个区间,如果该区间没出现过且没被之前的区间等效过,则可操作区间数目-1,具体原因可以自己推理下,原文中说的每一次动区间所有字母一起动,相当于该区间的组合数减少了26种,所以只要统计出这种区间出现了多少即可用二分快速幂求出结果。 区间合并的动机有点难想,原创 2014-03-01 20:26:35 · 1108 阅读 · 0 评论 -
poj1733 并查集+离散化
区间上的并查集,写过这类题的找到思路不难。 题目给的数的范围特别大,不得不离散化,这里采用map的方式来离散化。 具体解题思路可参考本博客hdu3038。 map离散化是指,比如1~10000,如果采用传统方式,明显是1和10000合并,但是离散化之后,用1代表1,2代表10000,1和2的合并便取代了1和10000的合并。采用map离散化,将原始值作为key,便能实现快速查找判断是否出现过原创 2014-03-08 19:06:30 · 1237 阅读 · 0 评论 -
poj1456 并查集or线段树
本来做并查集专题看到的题目,但是却是用线段树A掉的。。。并查集思路一会研究下,感觉这题用线段树做挺水的。 题目给的最后期限,就相当于给了线段树查找范围,在1~d范围内找还有没有空余的点,有的话则占用,更新线段树,单点更新,感觉比较简单。。。 #include #include #include using namespace std; #define lson l,m,rt<<1 #d原创 2014-03-07 22:28:38 · 1110 阅读 · 0 评论 -
poj1988 权值并查集
并查集 题目合并是指将一个集合按顺序摞在另一个集合上,比如1->2, 3->4; 1摞在3加完之后就成1->2->3->4. 解题思路:将顺序反过来,因为最后形成的肯定是一条链,所以将链反过来之后,每个节点到根节点的距离就是有多少个东西在他下面。 另注意只有一组数据。 #include #include using namespace std; const int N=3000原创 2014-03-06 20:53:45 · 881 阅读 · 0 评论 -
poj1703 种类并查集
种类并查集,比poj1182水 #include #include using namespace std; const int N=100005; int father[N]; int rank[N]; int n,m; void init() { memset(rank,0,sizeof(rank)); for (int i=0;i<=100000;i++)原创 2014-03-06 19:38:39 · 896 阅读 · 0 评论 -
hdu3047 带权并查集
带权并查集 #include #include using namespace std; int father[50005]; int rank[50005]; int n,m; int find(int x) { if (x == father[x]) return x; int t = father[x]; father[x] = find(原创 2014-03-06 10:22:51 · 736 阅读 · 0 评论 -
poj1182 种类并查集
有点坑的题目,不过做做绝对利大于弊,尤其在你不断WA到哭的时候,大神忽略这句 0:两者相同级别 1:被根节点吃 2:吃根节点 原因:对于输入的关系1和2,减1之后便是输入的两个量之间的关系(其实是写完题目之后看解题报告发现这规律的) #include #include using namespace std; int father[50005]; int rank[50005];原创 2014-03-06 17:47:45 · 787 阅读 · 0 评论 -
hdu3938 并查集+离线化
离线化不是离散化,离线化是指将所有数据获得,然后一次性输出结果,就像不是在线解决的一样。 没见过这种类型的题目,确实很难想到做法。这题目充分利用了并查集的性质,用类似最小生成树的做法逐渐得出结论。离散化是必要的,将边排序也是必要的,这样两个手段将题目的时间复杂度降低了不止一个档次。 题目意思看了好几篇题解报告才看懂,题目定义两个节点间的距离为两个节点所有路径上经过的点中任意相邻两点的边最长的那原创 2014-03-04 22:47:00 · 1368 阅读 · 0 评论 -
hdu3038
并查集。。。 第一次写带权并查集,感觉好难理解,看别人代码看了一上午才看懂,好弱菜的说。。。 所谓带权并查集,指的是在合并时不仅要将区间合并,而且要记录某些信息,记录的方法类似于数学的坐标系,以一个点为参考点(根节点),然后求出其他点到这个店的相对信息值,难点在于合并两个不同的集合时相对信息值的更新,分别在find和union里面进行更新,不理解的同学可以在纸上划一下,一边不懂多划几遍,表示我原创 2014-03-02 14:00:00 · 1760 阅读 · 1 评论 -
hdu3172
并查集水题。。。输入输出有点麻烦。。。1800多ms。。。超时的边缘 #include #include #include #include using namespace std; int father[100002]; int sum[100002]; int rank[100002]; int find(int x) { while (x!=father[x])原创 2014-03-01 22:45:35 · 917 阅读 · 0 评论 -
hdu1213+hdu1232
并查集水题。。。函数都不用改 #include #include using namespace std; int father[1001]; int rank[1001]; int sum; int find(int x) { while (x!=father[x]) x=father[x]; return x; } void Union(int a原创 2014-03-01 15:26:32 · 684 阅读 · 0 评论 -
poj1611
并查集水题。。。 #include #include using namespace std; const int max_size=30005; int rank[max_size]; int father[max_size]; int find(int d) { while (d!=father[d]) d=father[d]; return d;原创 2014-03-01 15:05:14 · 667 阅读 · 0 评论 -
hdu1272
并查集水题。。。因为输出大小写wa了好几次。。。 #include #include using namespace std; int rank[100001]; int father[100001]; int mark[100001]; int sum; int find(int x) { while (x!=father[x]) x=father[x];原创 2014-03-01 16:10:20 · 773 阅读 · 0 评论 -
poj1417 并查集+背包
题目意思很明确,给出相对关系和各种类人数,让求是否能确定所有人所属的种类,说no的两个人必然不在一类,说yes的必然在一类。 种类划分,由于只给了相对关系,很容易想到用种类并查集,区间合并多取几次异或就行了。 划分完成后,形成多个集合,每个集合由两部分组成,分别为与根节点相同的一类和与根节点不同的一类,用一个sum数组记录每个集合中每类人数。 要确定是否能将所有集合划分成两部分,就需要明确两原创 2014-03-10 08:51:31 · 1709 阅读 · 1 评论