zoukankan      html  css  js  c++  java
  • 简单的并查集

    • [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;
      }
  • 相关阅读:
    洛谷——P1951 收费站_NOI导刊2009提高(2)
    洛谷——P1475 控制公司 Controlling Companies
    洛谷——P1176 路径计数2
    洛谷——P1156 垃圾陷阱
    洛谷——P2734 游戏 A Game
    洛谷——P1767 家族_NOI导刊2010普及(10)
    洛谷——P1413 坚果保龄球
    Kali-linux破解LM Hashes密码
    Kali-linux分析密码
    Kali-linux密码在线破解
  • 原文地址:https://www.cnblogs.com/jiangjing/p/2990375.html
Copyright © 2011-2022 走看看