When using and looking up a set, if the number of lookups is many, then the use of the naïve version of the lookup must be timed out. For example, there are 1 million elements, every time from the 1 millionth start to find, such an operation is 10^6, if the program asked to find 10 million times, so down is 10^13, it must be a problem.
This is the code of the simple lookup, suitable for a small amount of data
Findx (x)
{
R=x;
while (parent[!=r)
R=parent[r];
R
}
Here's how to find the element using path compression:
Find (//Find the collection where the X element resides, and compress the path when backtracking )
{
if (parent[x])
{
parent[Find (parent[//Backtracking compression path
The nodes that pass from the X-node search to the ancestor node point to the Ancestor node.
parent[x];
}
The above is a recursive way to compress the path, but the recursive compression path may cause overflow stack, I used to because of this re n times, below we say a non-recursive way to do the path compression:
Next is the merged code, which guarantees that the small subtree can be attached to the large subtree.
There are many groups of students, students in the same group often contact, there will be new students to join. But SARS is very easy to infect, as long as the reorganization of a classmate infected with SARS, then all of the group's students are considered SARS. The task now is to figure out how many students are infected with SARS. It is assumed that the student with number 0 is suffering from SARS.
The idea of solving the problem----> obviously and check the set. A detailed explanation of the check set can be learned by clicking and checking the set (disjoint collection). Use num[] to store the number of elements in the collection and update num[when the collection is merged]. Then find the root node x of the collection where 0 is located, so num[x] is answer.
- Code highlighting produced by Actipro Codehighlighter (freeware) http://www. codehighlighter.com/--> #include <stdio.h>//by ktyanny
- #include <iostream>
- Using namespace std;
- const int maxn = 30001; / * Number of nodes on line * /
- int PA[MAXN]; /*p[x] Represents the parent node of x * /
- int RANK[MAXN]; /*rank[x] is an upper bound of the height of x * /
- int NUM[MAXN]; /*num[] Stores the number of elements in the collection and updates num[when the collection is merged] * /
- void Make_set (int x)
- {/* Create a unit set * /
- PA[X] = x;
- Rank[x] = 0;
- NUM[X] = 1;
- }
- int Find_set (int x)
- {/* Lookup with path compression * /
- / * Save the number you want to find * /
- int r = x, temp;
- / * Locate the root node * /
- while (pa[r]! = r) R = Pa[r];
- While (x! = r)
- {
- temp = pa[x];
- Pa[x] = r;
- x = temp;
- }
- return x;
- //if (x! = Pa[x])//commented out is actually OK, but do not want to use the return to do
- //Pa[x] = Find_set (pa[x]);
- //return pa[x];
- }
- /* Merges the collection of x, y by rank */
- void Union_set (int x, int y)
- {
- x = Find_set (x);
- y = Find_set (y);
- if (x = = y)return;
- if (rank[x] > Rank[y])/* make rank higher as parent node * /
- {
- Pa[y] = x;
- NUM[X] + = Num[y];
- }
- Else
- {
- Pa[x] = y;
- if (rank[x] = = Rank[y])
- rank[y]++;
- Num[y] + = num[x];
- }
- }
- Answer to 1611
- int main ()
- {
- int N, m, x, y, I, T, J;
- while (scanf ("%d%d", &n, &m))
- {
- if (m==n && n = = 0) break ;
- if (m = = 0)
- {
- cout << "1\n"; continue;
- }
- For (i = 0; i < n; i++)
- Make_set (i);
- For (i = 0; i < m; i++)
- {
- scanf ("%d", &t);
- scanf ("%d", &x);
- For (j = 1; j < T; j + +) {
- scanf ("%d", &y);
- Union_set (x, y);
- x = y;
- }
- }
- x = Find_set (0); / * Find the root of the 0 tree * * *
- //int ans = 0;
- //for (i = 0; i < n; i++)
- //if (pa[i] = = x)
- //ans++;
- //cout << ans << endl;
- cout << num[x] << Endl;
- }
- return 0;
- }
And find out the detailed