一、算法解释
用于解决一些有N个元素的集合应用问题。
1、将每个元素初始化为自身单独成为一个集合。用p[i]的值表示该元素所在集合。
2、现在我们想将3和1元素连线并成一个集合。可以将p[3] = 1。当p[3] != 3时说明该元素集合已经并入其他集合。
3、现在我们又将2与3连线并入一个集合,可以将p[2] = p[3]。
算法巧妙之处:一是利用集合中元素最大或最小节点编号作为集合标记,这样只要P[i]的值属于同一个值就表明他们属于一个集合;二是利用节点编号的大小关系形成一条链,通过这条链,我们可以搜索到当前元素所在集合标记。
二、代码
// 递归搜索当前节点所在子最小生成树标记。并在搜索过程中将同一子集的各节点标记置位该子集中最小节点号。
int find(int node){
if(flag[node]==node) return node;
else return flag[node] = find(flag[node]);
}
for(int j=0; j<m; j++){
// 搜索u,v节点所属子最小生成树标记
int x = find(edges[j].u);
int y = find(edges[j].v);
// 将路径中两个点归于同一子集,因为我们将同一子集中的最小节点号作为该子集的标记,那么将大的节点号标记置为小节点号。
if(x!=y){ // 防止出现回路
if(x>y)
flag[x] = y;
else
flag[y] = x;
}
}