zoukankan      html  css  js  c++  java
  • 算法导论之并查集

    /************************************************************************/
    /* *Author:justinzhang
    /*Email:uestczhangchao@gmail.com
    /*Establish:2011年5月14日16:43:46
    /*Discription:算法导论22章并查集&&poj1611                                                                     */
    /************************************************************************/
    
    #include<iostream>
    using namespace std;
    
    /*
    *rank[]是用来存放元素x秩的数组,p[]是用来存放元素x父节点的数组
    *Make_Set()用来初始化集合元素,刚开始的时候每个元素独立为一个集合
    */
    void Make_Set(int rank[],int p[],int x)
    {
        p[x] = x;
        rank[x] = 0;
    }
    
    /************************************************************************/
    /* 寻找x元素所属的集合                                                                     */
    /************************************************************************/
    int Find_Set(int p[],int x)
    {
        if(p[x]!=x)
        {
            p[x] = Find_Set(p,p[x]);
        }
        
            return p[x];
    
    }
    
    
    /************************************************************************/
    /* 合并两个集合                                                                     */
    /************************************************************************/
    void Union(int rank[],int p[],int x, int y)
    {
        int px = Find_Set(p,x);
        int py = Find_Set(p,y);
        if (rank[px]>rank[py])
        {
            p[py] = px;
        }
        else
        {
            p[px] = py;
            if (rank[px]==rank[py])
            {
                rank[py]++;
            }
        }
    }
    
    int main()
    {
        int n, m;
        int rank[30003];
        int p[30003];
        int numsuspect;
        int personnum;
        int firstpersonnum;
        int groupnum;
        int i,j;
        while(1)
        {
            numsuspect = 0;
            memset(rank,0,sizeof(rank));
            memset(p,0,sizeof(p));
            cin >> n >> m;//n为学生人数,m为学生的分组数
            if(n==0 && m==0)
                break;
            for(j=0;j<n;j++)
                Make_Set(rank,p,j);
            while((--m)>=0)
            {
                cin>>groupnum;
                if (groupnum>=1)
                {
                    cin>>firstpersonnum;
                }
    
                for(i=1;i<groupnum;i++)
                {
                    cin >> personnum;
                    Union(rank,p,firstpersonnum,personnum);
                }
                
            }
            for (j=0;j<n;j++)
            {
                if (Find_Set(p,0)==Find_Set(p,j))
                {
                    numsuspect++;
                }
            }
            cout << numsuspect << endl;
    
        }
        system("pause");
        return 0;
    }
    
    
  • 相关阅读:
    Jquery中的this指向的是哪个对象?
    需要重新编辑
    关于CSS选择器优先级无冲突样式设置的展示
    在 CSS 中,width 和 height 指的是内容区域的宽度和高度
    关于正则表达式中分组的一些误解勘正以及String的replaceAll方法误解勘正
    关于informatica的Dynamic Lookup组件使用中遇到的一个问题的思考
    【转】Informatica Update 机制详解
    维度表和事实表的含义
    今天看IO流,复制word遇到的一个小问题
    小试下新博客,一个列传行的SQL
  • 原文地址:https://www.cnblogs.com/justinzhang/p/2450609.html
Copyright © 2011-2022 走看看