POJ1611 The Suspects

These elements are combined into a set for each m by using the union lookup set. Use sum array to record the number of elements in the same collection. Finally, query the sum number of root nodes of element 0, which is all the students suspected of SARS.

 

And query set is mainly used for query and consolidation. Query is the basis of consolidation.

Four operations are needed for the implementation of concurrent query set:

  • (1)init: initialization
  • (2)find: queries and returns the root of the tree
  • (3)unite: merge the set where x is and the set where y is
  • (4)same: query whether x and y belong to the same collection (whether there is a common ancestor)


To record the number of elements, you can open a global array sum, and assign sum[i] to 1 during initialization. When merging sets, add the number of subordinate sets to the set with the largest Rank value.

 

The C + + code is as follows:

In particular, the array name rank that records the height of the tree conflicts with the C + + keyword, so it should be changed to rank

//(1)init: initialization
//(2)find: queries and returns the root of the tree
//(3)unite: merge the set where x is and the set where y is
//(4)same: query whether x and y belong to the same collection (whether there is a common ancestor)
#include <iostream>
#include <cstdio>
using namespace std;

const int MAX_N = 30010;
int par[MAX_N]; // father
int Rank[MAX_N]; // Height of tree
int sum[MAX_N];

// Initialize n elements
void init(int n) // Do not forget to initialize!!!
{
    for (int i = 0; i < n; i++)
    {
        par[i] = i; // Initialize i's father: at first, each node is its own ancestor
        Rank[i] = 0; // Initialize the height of i. at the beginning, each node is its own ancestor, namely the tree root, and the height of the tree root is 0
        sum[i] = 1;
    }
}

// Query and return the root of the tree
int find(int x)
{
    if (par[x] == x)
        return x;
    else
        return par[x] = find(par[x]); // return a = b; that is, assign the value of b to a and return the value of a
                                      // This means assigning x's father's father to x's father, which is known to find a root node up the trunk
}

// Merge the set of x and y
void unite(int x, int y)
{
    x = find(x); y = find(y); // Assign the roots of x and y to x and y, respectively
    if (x == y) return; // If x has the same root as y, you do not have to merge

    if (Rank[x] < Rank[y]) ///When merging, if the height of two trees is different, connect the Rank small to the top of the Rank
    {
        par[x] = y;
        sum[y] += sum[x];
    }
    else
    {
        par[y] = x;
        sum[x] += sum[y];
        if (Rank[x] == Rank[y]) Rank[x]++; // If it is the same, the highest height needs to be + 1 on the original basis after merging
    }
}

bool same(int x, int y) // Determine whether x and y belong to the same set
{
    return find(x) == find(y); // Just judge whether the root nodes of x and y are the same
}

int main()
{
    int n, m;
    int k, one, nexts;
    while (scanf("%d%d", &n, &m) != EOF)
    {
        if (n == 0 && m == 0)
            break;
        init(n);
        while (m--)
        {
            scanf ("%d", &k); 
            scanf ("%d", &one); // Merge this data into a collection union
            k--;
            while (k--)
            {
                scanf ("%d", &nexts);
                unite(one, nexts);
            }
        }
        printf ("%d\n", sum[find(0)]);
    }
    return 0;
}

 

Posted by xoligy on Sun, 05 Jan 2020 01:16:37 -0800