第十周总结

第十周,因为上周没有提交博客,所以就有了很多时间来看博客和看并查集的例题。

对于我来说,并查集是一个全新的知识,并查集的名字上可以看出他处理的是集合之间的关系:“合并”和“查找”。和运用集合的形式将元素关联起来。但是遇到并查集问题,一般我看到后第一感觉是用搜索来解决,有些题目也是真的可以用搜索来处理,但是在看博客以及上课的时候我知道了这些题目有搜索来处理的话,会过于复杂,从做题的角度来说用并查集会简单很多。这些情况也只能在下周做题来仔细地体会。

对于并查集的处理,结点的处理是关键,通过根结点编号压缩路径,通过它来寻找判断是否属于同一集合。路径压缩是通过递归实现的,这并不难理解,因为在图中对于元素是否属于同一结点的判断时,需要用父节点来判断,此时需要通过往父结点寻找判断是否相同。

初始化

void setfa()
{
int i = 1;
for(i = 1; i <= N; i++)
{
fa[i] = i; // 初始化时, 将自己初始化为自己的上一级
}
}

查找祖先

int findfa(int n) 
{
	int r = n;
	while(fa[r] != r)
	{
		r = fa[r]; // 没找到的话, 一直往上找
	}
	return r;
}

合并


void uniteSet(int faX, int faY)//x和y是已经知道的两个最高父类,即所有人的祖先
{
	fa[faX] = faY;  
}

路径压缩

    int i=x , j ;
    while( i != r )                                                                                                        
    {

         j = pre[ i ]; // 在改变上级之前用临时变量 j记录下他的值 
         pre[ i ]= r ; //把上级改为根节点
         i=j;

    }
    return r ;
}

 

联系寻找与合并

void bcj(int x,int y)//并查集
{
	int x1=find(x),y1=find(y);//找爸爸
	if(x1!=y1)pre[y1]=x1;//爸爸不一样就合并
}

并查集说到底就是把元素标记,通过标记确定顶点所在的集合,通过一级一级的回溯确认,比起搜索算法他可能不需要那么复杂,但是理解确实十分重要,还是需要通过并查集洛谷例题进行锻炼,做到能够判断出在什么时候用并查集处理问题还有在处理不同问题时的思路。

思路是最重要的,然后把具体思路分成几个函数去完成,所以更是有成百上千种做法,所以当我做这些题的时候,也会觉得这道题我写的太麻烦了,很多都没有必要,以后如果想提高自己,那就必须要寻找最优解,使程序看起来更加的完美简洁。希望通过对于洛谷并查集题目的训练可以提高自己,掌握这个算法运用好他。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值