这是一个全裸的并查集,其实就是求有多少个不同的连通分量。第一次用并查集,理解的差不多了,接下来就是应用啦。

CODE:

#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
const int maxn = 1002;

int p[maxn];       //p用来记录父节点 
int rank[maxn];    //rank用来记录节点数 


int find(int x)
{
    return p[x] == x? x : p[x] = find(p[x]);
}

void Union(int x, int y)
{
    int i = find(x);
    int j = find(y);
    if(i == j) return ;
    if(rank[i] > rank[j])        //压缩路径 
    {
        p[j] = i;              //如果i节点数大于j的节点数那么,则令j指向i; 
    }
    else
    {
        p[i] = j;              //如果j节点数大于i的节点数那么,则令i指向j;
        if(rank[i] == rank[j]) //压缩路径 
        {
            rank[j]++;
        }
    }
}


int main()
{
    int N, M;
    while(~scanf("%d", &N) && N)
    {
        int i, j, tot;
        memset(rank, 0sizeof(rank));
        for(i = 0 ; i <= N; i++) p[i] = i;
        for(scanf("%d", &M); M > 0; M--)
        {
            int a, b;
            scanf("%d%d", &a, &b);
            Union(a, b);
        }
        for(tot = -1, i = 1 ; i <= N; i++) if(p[i] == i)    tot++;
        printf("%d\n", tot);  //tot
    }
    return 0;
}

posted on 2012-07-24 09:46  有间博客  阅读(146)  评论(0编辑  收藏  举报