简单的并查集

  • [1392] 我们必须向前推进!你要来一包么

  • 时间限制: 1000 ms 内存限制: 65535 K
  • 问题描述
  • 现在初中生高中生竟然开始抽烟了,真是太不像话了,不过作为一个无奸不商的烟草商,小白菜已经瞄准这块商机无限的市场了。他知道在某个学校里有n(5 <= n <= 50000)个学生,可人家毕竟是学生,直接询问他抽什么烟不太好,学生们也不愿意说,真烦躁。不过小白菜想到了一个办法,就是每次抓两个人来询问是不是抽同一种烟。每次他都会记下回答是yes的两个学生,一共记了q(2 <= q <= n*(n- 1)/2)对学生。现在小白菜捧着一大堆数据来找你,他不需要知道每个人抽什么烟,只需要知道有几种烟能卖到这个学校,你能解决这个难题吗?
  • 输入
  • 有多组输入,每组数据的开头包含两个整形n(5 <= n <= 50000)和q(2 <= q <= n*(n- 1)/2),接下来跟着q行,每行为两个学生的ID。
  • 输出
  • 对于每组数据,输出共有多少种的烟即可。
  • 样例输入
  • 5 2
    1 2
    4 5
    
  • 样例输出
  • 3
    
  • 可以说是一道简单的并查集,但是我一开始竟然超时了,后来发现原来是没有进行路径压缩,压缩之后才A了
  • 代码实现:
  • #include<stdio.h>
    #include<string.h>
    int a[50001];
    int find(int x)
    {
        int yuan=x,hou,temp;
        while(x!=a[x])
        {
            x=a[x];
        }  
        hou=x;
        while(hou!=a[yuan])//路径压缩,开始这一部分是木有的
        {
            temp=yuan;
            yuan=a[yuan];
            a[temp]=hou;
        }
        return x;
    }
    int main()
    {
      int i,n,q,t1,t2,num;
      while(scanf("%d%d",&n,&q)!=EOF)
      {
          num=0;
          for(i=1;i<=n;i++)
              a[i]=i;
          for(i=1;i<=q;i++)
          {
              scanf("%d%d",&t1,&t2);
              t1=find(t1);
              t2=find(t2);
              a[t1]=t2;
          }
          for(i=1;i<=n;i++)
              if(a[i]==i)
                  num++;
          printf("%d\n",num);
      }
      return 0;
    }
原文地址:https://www.cnblogs.com/jiangjing/p/2990375.html