并查集的基本知识:
http://www.nocow.cn/index.php/%E5%B9%B6%E6%9F%A5%E9%9B%86
并查集的操作包含并和查两个步骤。在并操作中,就是将子节点连接到父亲节点上,形成一颗树。这样直接连接的话在查操作的时候就会发现当树是一条直线时时间复杂度会打到O(n),所以我们可以用压缩的办法,将子树的根节点下的所有点直接连接到子树的根节点上,这样就可以直接查找到原始父节点。
并查集的代码:
TOJ 2469
#include <iostream>
#include <cstdio>
#define MAX 120
using namespace std;
int parent[MAX];
int n,m;
int find(int x)
{
if(parent[x]!=x)
{
parent[x]=find(parent[x]); //在查找的过程中压缩路径
}
return parent[x];
}
void Union(int s,int e)
{
int root_s=find(s),
root_e=find(e);
if(root_s==root_e)
return;
parent[root_s]=root_e;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n>>m;
for(int i=1; i<=n; i++)
{
parent[i]=i;
}
for(int i=1; i<=m; i++)
{
int s,e;
cin>>s>>e;
Union(s,e);
}
int sum=0;
for(int i=1; i<=n; i++)
{
if(i==find(i))
sum++;
}
cout<<sum<<endl;
}
return 0;
}