并查集的算法应用
- 欧拉回路中判断图是否联通
 - 最小生成树克鲁斯卡算法—Kruskal算法
 
并查集模板
并查集可以实现两个,查找与合并
并查集是一个树的结果,总的还说是森林
可以判断两个结点是否在一个图中,或一个图是否连通
或者实现找朋友题,朋友可以传递,判断谁和谁是否是朋友
房间是否连接
是否为亲戚
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int fa[10005];
int father(int x){
    if(fa[x]==x)return x;
    return fa[x]=father(fa[x]);//动态规划策略,直接
}
void unionn(int x,int y){
    fa[father(y)]=father(x);
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            fa[i]=i;
        }
        for(int i=0;i<m;i++){
            int z,x,y;
            scanf("%d%d%d",&z,&x,&y);
            if(z==1){
                unionn(x,y);
            }else if(z==2){
                printf("%s\n",father(x)==father(y)?"Y":"N");
            }
        }
    return 0;
}
例题:
HUD1232畅通工程
http://acm.hdu.edu.cn/showproblem.php?pid=1232
在最后结果中,一棵树上的结点的根结点不一定相同,但是,题目的根结点总会一棵树上
判断有几棵树的方法是,判断根是否为本身序号,因为根的根结点就是本身
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int fa[1005];
int father(int x){
    if(fa[x]==x)return x;
    return fa[x]=father(fa[x]);//动态规划策略,直接
}
void unionn(int x,int y){
    fa[father(y)]=father(x);
}
int main(){
    int n,m;
    while(scanf("%d",&n)!=EOF&&n){
        scanf("%d",&m);
        for(int i=0;i<=n;i++)fa[i]=i;
        for(int i=0;i<m;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            unionn(a,b);
        }
        int sum=0;
        for(int i=1;i<=n;i++){
            if(fa[i]==i)sum++;
        }
        printf("%d\n",sum-1);
    }
}
HUD How Many Tables
http://acm.hdu.edu.cn/showproblem.php?pid=1213
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int fa[1005];
int father(int x){
    if(fa[x]==x)return x;
    return fa[x]=father(fa[x]);//动态规划策略,直接
}
void unionn(int x,int y){
    fa[father(y)]=father(x);
}
int main(){
    int t;
    cin>>t;
    while(t--){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=0;i<=n;i++)fa[i]=i;
        for(int i=0;i<m;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            unionn(a,b);
        }
        int sum=0;
        for(int i=1;i<=n;i++){
            if(fa[i]==i)sum++;
        }
        printf("%d\n",sum);
    }
    return 0;
}