4 2 1 3 4 3 3 3 1 2 1 3 2 3 5 2 1 2 3 5 999 0 0
1 0 2 998
思路:
第一次做并查集的题,总体感觉还是有点别扭,没有完全理解并查集的思想,在这里把并查集的思路整理一下...
1,find( )查找双亲节点,若节点a不是根节点,则查找a的双亲节点,并在pre数组中返回根节点的值。
2,路径压缩的意义则在于除将根节点的的所有节点都移到根节点的孩子节点处,更便于对数据的操作。
3,join( )函数的意义则在于判断两个分值是否连通,若分支不联通,则进行合并,若分支连通,则不与操作。
本题中find( )没有单独写成子函数,源码为:
# include<iostream>
using namespace std;
int pre[1000];
int find(int x)
{
int r=x;
while(pre[r]!=r)
r=pre[r];
int i=x;
int j;
while(i!=r)
{
j=pre[i ];
pre[i ]=r;
i=j;
}
return r;
}
int main()
{
int n,m,p1,p2,i,total,f1,f2;
while(cin>>n && n!=0)
{
total=n-1;
for(i=1;i<=n;i++){
pre[i]=i;
}
cin>>m;
while(m--)
{
cin>>p1>>p2;
f1=find(p1);
f2=find(p2);
if(f1!=f2)
{
pre[f2 ]=f1;
total--;
}
}
cout<<total<<endl;
}
return 0;
}