题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1232
所谓并查集,就是指查找无向图或是有向图中各个点的联通与否,其中可以分为两个部分,一个是根节点的寻找,一个是联通过程。首先在根节点的寻找中使用储存前驱节点信息的数pre[],
逐层询问,直到最上的点;如果两个点的最上的点不同那么就需要将他们联通,联通的方法就是将其中一个最上点的前驱节点转为另一个最上点,这要两个块就顺利联通了。
路径压缩:把每次找到的前驱节点都指向他们的最上点这样下次寻找就只用向上查找一层就可以得到最上点的信息了。
具体代码如下,详情见注释:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int pre[1010];
int n,m;
int find_root(int x){return pre[x]==x?x:pre[x]=find_root(pre[x]);}
//自带路径压缩的寻找根节点的函数,巧妙地使用了三目运算符
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0)return 0;
memset(pre,0,sizeof(pre));
for(int i=1;i<=n;i++)
{
pre[i]=i;
}
int rx,ry;
for(int i=0;i<m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
rx=find_root(x);
ry=find_root(y);
if(rx!=ry)//链接过程,也可以单独构建函数;
{
pre[ry]=rx;//改变一个点的前驱点到另一点
}
}
int ant=0;
for(int i=1;i<=n;i++)
{
if(pre[i]==i)
{
ant++;
}
}
printf("%d\n",ant-1);
}
return 0;
}
仅代表个人观点,欢饮交流探讨,勿喷~
PhotoBy:WLOP