并查集~

http://acm.hdu.edu.cn/showproblem.php?pid=1232

详细介绍,很有意思:http://blog.csdn.net/dellaserss/article/details/7724401

#include <iostream>
using namespace std;
int parent[1050];
bool t[1050];
int find(int x)
{
    int r = x;
    while(r!=parent[r])
        r = parent[r];
    int i = x ,j;
    while(parent[i]!=r) //压缩路径
    {
        j = parent[i];
        parent[i] = r;
        i = j;
    }
    return r;
}
void union_set(int x ,int y)
{
    int fx = find(x);
    int fy = find(y);
    if(fx!=fy)
    {
        parent[fx] = fy ;
    }
}
int main()
{
    int N,M,i,j;
    int a,b;
    int ans =0;
    while(scanf("%d",&N))
    {
        if(N==0)
            break;
        scanf("%d",&M);
        for (i =1 ;i<=N;i++)
        {
            parent[i] = i;
        }
        for(i =1 ;i<=M;i++)
        {
            scanf("%d %d",&a,&b);
            union_set(a,b);  //合并集合
        }
        memset(t,0,sizeof(t));
        for(i=1 ;i<=N;i++)
            t[find(i)] = 1; //标记根结点
        ans = 0;
        for(i =1;i<=N;i++)
            if(t[i])
                ans++;
        printf("%d\n",ans-1);
    }

    return 0;
}
原文地址:https://www.cnblogs.com/cheng07045406/p/3107797.html