这题读懂了很容易想到解决的办法,答案就是集合个数-1。所以重点就在于写这个并查集。
并查集的建立和并查集的两个基本操作,即合并merge和查找find。
一开始我没写find函数,默认输入的两个就是根节点了,然后就wa了。我还把find删了以为就只要用merge。但很多时候find和merge都是一起出现的。
#include<bits/stdc++.h>
using namespace std;
int q[1010];
int find(int x)
{
int r=x;
while(r!=q[r])
{
r=q[r];
}
return r;
}
void merge(int a,int b)
{
int x1=find(a);
int x2=find(b);
if(x1==x2) return;
else q[x2]=x1;
}
int main()
{
int n,m;
while(scanf("%d %d",&n,&m))
{
if(n==0) break;
for(int i=1;i<=n;i++) q[i]=i;
for(int i=1;i<=m;i++)
{
int a,b;
cin>>a>>b;
merge(a,b);
}
int ans=-1;
for(int i=1;i<=n;i++)
{
if(q[i]==i) ans++;
}
cout<<ans<<endl;
}
return 0;
}
简单看看ac代码,还是有几点是可以提一下的。一开始对并查集q数组的初始化。 在没有输入路的时候,没有进行合并的时候,一开始每一个顶点都是自己的根节点。然后才开始进行合并操作。
看merge函数,在对a和b两个顶点进行合并操作的时候。是对这一整个大集合操作,所以要先找到这a和b的根节点祖宗。然后进行合并操作之前,要先判断这两个顶点是不是已经是一个集合的了。
最后再给几点其他的建议。我也知道会看这个的人都什么成分哈哈哈。学好使用sort函数和merge函数。sort函数包过要会写它的cmp函数,能够自己定义比较的方式,就会很轻松。