POJ 1611 The Suspects(并查集)

http://poj.org/problem?id=1611

 并查集就意味着对于联通分量的完美运用

开一个num数组可以记录子孙节点个数

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define maxn 30090
int n,m;
int fa[maxn];
int num[maxn];
int find(int x)
{
    int f=fa[x];
while(f!=fa[i])// 一开始写成 if(f!=fa[f])结果还以为是路径压缩错了
    {
       f=fa[f];
    }
    int j;
   /* while(x!=f)
    {
        j=fa[x];
        num[j]-=num[x];
        fa[x]=f;
        x=j;

    }*///1.不用压缩也一样2.注意num更新必须在x变化之前!!3.num【f】不必更新

    return f;
}
void makeset(int x,int y)
{
    int fx=find(x),fy=find(y);
    if(fx!=fy)
    {
        fa[fx]=fy;
        num[fy]+=num[fx];
    }


}
int main()
{
    while(scanf("%d %d",&n,&m)&&(n||m))
    {
      int i;
      for(i=0;i<n;i++)
      {
          fa[i]=i;
          num[i]=1;
      }
      for(i=0;i<m;i++)
      {
          int k,u;
          scanf("%d %d",&k,&u);
          int j,p;
          for(j=1;j<k;j++)
          {
            scanf("%d",&p);
            makeset(p,u);
          }
      }
      printf("%d\n",num[find(0)]);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值