This is the fourth day of my participation in Gwen Challenge
The introduction
Omnipresent religion
There are so many religions in the world. Suppose you are interested in how many religions your classmates have in total. We know there are n students in the school, but it is not polite to ask people about their religious beliefs directly. Another way is to ask m and his classmates whether they believe in the same religion. Based on this information, how would you be smart enough to figure out the maximum number of religious faiths at your school?
An overview of the
==Union-Find Set==
A == tree data structure == is used for merging and querying some Disjoint Sets
In use, it is usually represented by forest
Initialize: set the numbers to 1… N elements of N are divided into N disjoint sets, and in each set, one element is selected to represent the set (usually represented by the root node).
Common operations:
•**== Merges ==** two sets
•**== Finds ==** which collection an element belongs to
• Determine whether two elements belong to the same set
Basic operation
To determine whether two elements belong to the same set, you just need to determine whether the root of the set is the same
Merge two sets, using the root of one set as the root of the other
The basic function
Make_set (x) : Initializes each element as a set
Find_set (x) : Finds the collection of an element. When you perform a search, you follow the parent until you find the root
Union_set (x, y) : use find_set() to find the root of two sets and point the root of one set to the root of the other set
Heuristic strategy optimization
According to the rank merger
• Rank: The height of the tree where only one root node has Rank 0
•==union_set(x,y) merges by rank ==, == Merges relatively small rank trees into relatively large rank trees, so that the height of the merged tree will be relatively small ==
Path to the compression
• Path compression when find_set(x), after the root node is found by “recursion”, the parent of all nodes on the path points directly to the root node when “backtracking”, and the time complexity is O(1) when find_set(x) is called again.
#include <stdio.h>
const int MAXN = 100; /* Number of nodes */
int pa[MAXN]; /*pa[x] indicates the parent of x */
int rank[MAXN]; /*rank[x] is an upper bound on the height of x */
/* Create a cell set */
void make_set(int x)
{
pa[x] = x;// it is its own parent node,
rank[x] = 0;// The initial node has its own node with rank 0
}
/* Lookup with path compression */
int find_set(int x)
{
if(x ! = pa[x])// My parent is not my own, so I continue to search until I find my own father
pa[x] = find_set(p[x]); // Trace the parent of all nodes back to the root
return pa[x];
}
/* Merge the set of x and y by rank */
void union_set(int x, int y)
{
x = find_set(x); // Return the root of x
y = find_set(y); // return the root of y
if(rank[x] > rank[y])/* set the parent of a higher rank */
pa[y] = x;// The rank of x, where x is the father and y is the son of X
else
{
pa[x] = y;// Otherwise, x's father is Y
// The rank of y is the same. It doesn't matter who the father is, but if y is the father first, the rank of y will increase by 1
if(rank[x] == rank[y]) rank[y]++; }}Copy the code
Example: PTA circle of Friends (25 points)
Circle of Friends (25 points) A school has N students, forming M clubs. Students in each club have certain similar interests, forming a circle of friends. A student can belong to several different clubs at once. If A and B are friends, and B and C are friends, then A and C are friends, too. Please write a program to calculate the number of people in the largest circle of friends.
Input format: The first line contains two positive integers N (≤30000) and M (≤1000), representing the total number of students and the number of clubs respectively. The following M lines give the information of one club in the following format, where students are numbered from 1 to N:
Number of people in club I Mi (blank) Student 1 (blank) Student 2… Students in the Mi
Output format: The output gives an integer representing the number of people in the largest circle of friends.
Example Input:
1. 3Copy the code
Example output:
4
Copy the code
After all nodes are merged, the parent nodes of all nodes are traversed, and the number of fathers of the parent node is recorded, and the number of fathers of the parent node is compared to whether it is the father with the most sons. The largest number of sons is recorded and output.
In the code
#include "bits/stdc++.h"
using namespace std;
const int maxx = 30005;
int father[maxx];
int ran[maxx];
int isRoot[maxx];
void make_set(int x)
{
father[x] = x;
ran[x] = 0;
}
int find(int x)
{ // Find the compression path
if (father[x] == x)
{ // If its parent is itself, then x is the root
return x;
}
return find(father[x]); // Return the root of the parent
}
void merge(int x, int y)
{
x = find(x);
y = find(y);
if (x == y)
return;
if (ran[x] > ran[y])
{
father[y] = x;
}
else
{
father[x] = y;
if(ran[x] == ran[y]) { ran[y]++; }}}int main(a)
{
int n, m;
cin >> n >> m;
for (int i = 0; i <= n; i++)
{
make_set(i);
}
int x, y;
int k;
int s = 1;
for (int i = 0; i < m; i++)
{
cin >> k >> x;
for (int j = 0; j < k - 1; j++)
{
cin >> y;
merge(x, y); }}int ans = 0;
for (int i = 1; i <= n; i++)
{
int f = find(i);
isRoot[f]++;
ans = max(ans, isRoot[f]);
}
cout << ans << endl;
}
Copy the code