ZOJ 1789 水水的并查集,刚开始学会并查集,做了此题。经过一次失败后终于AC了哈哈~ AC感觉就是好啊!与大家共分享啊

#include<stdio.h>
#include<stdlib.h>
#define N 30000
#define M 500

int rank[N], father[N],num[N];  /* rank指代数的层数,num指每个节点数目 */
 
int Make_set(int x)    /* 初始化父节点 */
{
   int i;
   for (i=0; i<x; i++)
   {
     father[i] = i;
     rank[i] = 0;
     num[i] = 1;
   }
}

int Find_set(int x)         /*  寻找父节点,运用递归查找 */
{
    if (x != father[x])
     father[x] = Find_set(father[x]);
    return father[x];
}
      
int Union(int x,int y)     /* 归并相同节点的树,并记录该节点的数目 */
{
   x = Find_set(x);
   y = Find_set(y);
   if (rank[x] > rank[y])
   {
     father[y] = x;
     num[x] += num[y];
   }
  else if(rank[x] < rank[y])
   {
     father[x] = y;
     num[y] += num[x];
   }
   else if(x != y)
   {
      father[y] = x;
      rank[x]++;
      num[x] += num[y];
   }
}

int main()
{
    int i, k, b, p;
    int n, m, a;
   
    while(scanf("%d %d", &n,&m) != EOF)
    {
        if(n==0 && m==0) break;
           Make_set(n);
        while(m--)
        {
           scanf("%d", &k);
           scanf("%d", &a);
           for(i=1; i<k; i++)
           {
              scanf("%d", &b);
              Union(a,b);
           }
        }
        p = Find_set(0);  /*  寻找0节点的位置 */
        printf("%d\n", num[p]);
    }
    return 0;
}  
 

posted @ 2011-08-14 10:35  zhongya  阅读(138)  评论(0编辑  收藏  举报