先上一个图
再来一个代码进行解析:
#include <iostream>
#include <cstring>
using namespace std;
int f[50];
void init(int n)
{
for(int i=1;i<=n;i++) f[i]=i;
}
int getf(int a)
{
if(f[a]==a) return a;
else
{
f[a]=getf(f[a]);
return f[a];
}
}
void merge(int a,int b)
{
int t1,t2;
t1=getf(a);
t2=getf(b);
if(t1!=t2)
{
f[t1]=t2;
}
}
void print(int n)
{
for(int i=1;i<=n;i++) cout<<"("<<i<<")"<<f[i]<<" ";
cout<<endl;
}
int main(int argc, const char * argv[]) {
int n,m,a,b,sum;
sum=0;
cin>>n>>m;
init(n);
for(int i=1;i<=m;i++)
{
cin>>a>>b;
merge(a,b);
print(n);
}
for(int i=1;i<=n;i++)
{
f[i]=getf(i);
}
for(int i=1;i<=n;i++)
if(f[i]==i) sum++;
cout<<sum<<endl;
return 0;
}
3 3
1 2
2 3
3 1
起先我们先对输入的这些数判断,起先对初始化为自己是自己的父节点,1 2说明有关系,然后这里f[1]=2;就是把1作为2的子节点图上说明,打叉说明节点连接到别的节点上去,在2 3,这里2和3的父节点都是本身,不相等,就把2连接到3上(即2为3的父节点),3 1这里3的父节点是3,1的前一个节点是2,但是不是1的父节点所以要在继续找到3,即相等说明不用连。就有最后一个图1->2->3, 1 2 的父节点就是3 说明是一个集合里面的。
哎 !!!总结:自己有做过几道并查集的题目,以为那时候懂了这个,没想到昨晚的一道题目反而从新理解了并查集,刷题刷题。