随笔分类 - 并查集
摘要:这道题一开始的思路不过严谨,忽略 了一种情况,悲剧,本想一次过的这题不难,跟前面的某一到题目类似,不过不是求集合的元素个数,而是求有多少个集合具体思路很简单,在代码中……#include<stdio.h>#define MAXN 50010int f[MAXN],r[MAXN],n,num;int find(int x){ if(x!=f[x]) f[x]=find(f[x]); return f[x];}void Union(int x,int y){ int a=find(x); int b=find(y); if(a==b)//若父节点相同,则表示都出现过了,不同,则表示有一
阅读全文
摘要:这题,额,思路很好理解,说难其实也不难,代码也很好实现,就是慢了一点,不知道大牛是怎么过的,十分的好奇ing//题意:题目给出 n 台电脑,距离 d,和各台电脑的坐标(x,y)。电脑要通信要满足两个条件:// 1 电脑被修好,2 电脑之间的距离不超过距离 d 。输入 O p 时代表电脑 p 被修好,输入 S p q 时//代表测试电脑 p 与 q 之间是否可以通信。//思路:用到并查集。如果修好的电脑和已经被修好的电脑之间的距离小于 d ,则合并。//最后判断两台电脑是否可以通信就通过判断电脑是否被修好,根结点是否相等。#include<stdio.h>#include<ma
阅读全文
摘要:额, 这题怎么说呢,一开始觉得很难,可是看了别人的思路之后,觉得还可以吧判定是否为树:1):每个节点的入度为0或12):只有一个根节点3):不构成环其他的,在代码中已经有解释了#include<stdio.h>#define MAXN 1010int f[MAXN], r[MAXN],k[MAXN];//f[]记录该节点的父节点,r[]记录该节点的子节点个数,k[]记录该节点是否出现过int find(int x){ if(x!=f[x]) f[x]=find(f[x]); return f[x];}//查找父节点,路径压缩,其实,在这里已经把子节点都连接到根节点上了int dec
阅读全文
摘要:这道题,在前一道题目的基础上,好理解多了,个人在代码中写了自己的一点理解也算是一个拓展应用吧,个人感觉对并查集有了更深的理解了,具体怎么样,继续做题看看吧大牛还给了一个一般情况下维护偏移量的公式感谢这位大牛分享:这里将两个集合并起来并将所挂集合偏移量指向:kind[b]=(kind[x]-kind[y]+4)%3;想想上一题是不是也很类似呢其实上一题的公式也可以改成kind[b]=(kind[x]-kind[y]+3)%2; 不管是几个动物循环,都能得到类似的结论,所以以后碰到4,5,6,7。。。个动物的食物链,你应该也会做了吧?^_^View Code #include<stdio.h
阅读全文
摘要:唉,这道题更是让我花费了不少时间,好多大牛都说很简单,但是…………很无语就对了,一下部分接受转自http://www.cppblog.com/abilitytao/archive/2010/05/14/98899.html大牛虽然解释了好多,但综合了很多的博客里面的介绍之后,我终于有了些许的感悟,我想,结合我在程序中的注释应该会容易理解一点大牛的介绍:题目的大意是给出n只bug和m次观察到的性行为,并以此为依据判断两只bugs是不是有同性恋行为(gay)。比如3只bug1 2有性行为2 3有性行为1 3有性行为---->>>>>首先1,2是异性。---->&
阅读全文
摘要:嘿嘿,第一道并查集的题目,一个基本的应用,求一个集合的元素个数,不过中间同样涉及了俩个基本的操作,查找还有合并题目大意:有n个学生(标号为0 to n-1),m个学生社团,给出每个社团里所有学生的标号,并假设0号学生患有SARS(社团里只要用一个学生患病,则整个社团里的学生都会被隔离),问最后一共会有多少学生被隔离?这是一个最基础的并查集的应用,扫描每一个社团,只要两个学生出现在同一个社团,则将这两个集合合并起来,最后输出0号点所在集合的rank值集合(rank值记录这个集合中的元素个数并用一个flag值跟踪0号元素所在集合标号)即可。#include<stdio.h>#defin
阅读全文