今天第一次接触并查集这个神马东西,花了二个小时去搞懂一些基本的东西;
并查集思想:1.并查集是用来处理两个不相交集合的问题
2.以树为基础,组成一个森林,一棵树代表一个集合
3.判断两个元素是否在同一集合中,只要知道是否在同一棵树中,也就是是否具有相同的根结点;
4.压缩路径:在寻找根结点过程中
5.合并两个集合
下面是hdu1232的代码:
#include<iostream>
#include<vector>
using namespace std;
int find_father(int x,vector<int>& father){
if(x == father[x])
return x;
else{//回溯压缩路径
father[x] = find_father(father[x],father);
}
return father[x];
}
void merge(int a,int b,vector<int>&father){
father[a] = b;
}
int main()
{
vector<int> father;
int nTown;
int nWay;
while(cin >>nTown && nTown){
father.push_back(0);
for(int i = 1;i <= nTown;i++){//初始化父结点为自己
father.push_back(i);
}
cin >>nWay;
for(int i = 0;i < nWay;i++){
int a,b;
int _a,_b;
cin >>a >>b;
_a = find_father(a,father);
_b = find_father(b,father);
if(_a != _b){//在不同的集合中,而现在得知两下城填之间有路,固两个集合中的每一个城镇都可通达,固合并为一个集合
merge(_a,_b,father);
}
}
int count = -1;
for(int i = 1;i <= nTown;i++){//判断有多少个根结点,也就是有多少个集合,要使它们合并起来就要建n-1条路,这里count初始化为-1;
if(i == father[i])
count++;
}
cout <<count <<endl;
father.clear();
}
}