借鉴:传送门 思路:并查集即将所有的独立集合中,有关系的集合链接起来,形成一个新的集合,最后达到划分众多数据的目的。
运用了数据结构中的树来实现。
核心构成有pre[i] = root.代表i的父类是root. i的超级父类即为i与root的共同父类。可以理解为超类是i与root的掌门,root是i的上级。
find函数 查找超级父类 同时实现路径压缩。
join函数 将有关系的两个点的父类放在同一个集合中达到减小划分区域的目的。即为并。
传送门 AC代码:
using namespace std;
int pre[1005];
int n, m;
int Find(int root)
{
int son = root;
while(pre[root] != root)
root = pre[root];
while(son != root)//tmp保存前驱结点
{
int tmp = pre[son];
pre[son] = root;
son = tmp;
}
return root;
}
int main()
{
while(~scanf("%d", &n) && n != 0)
{
scanf("%d", &m);
for(int i = 1; i <= n; i++)
pre[i] = i;
int cnt = n;
for(int i = 1; i <= m; i++)
{
int u, v;
int root1, root2;
scanf("%d %d", &u, &v);
root1 = Find(u);
root2 = Find(v);
if(root1 != root2)
{
pre[root1] = root2;
cnt--;
}
}
printf("%d\n", cnt - 1);
memset(pre, 0, sizeof pre);
}
return 0;
}
路径压缩详解
并查集详解