Query set: (Union-findsets)
A simple and widely used set. the query set is a set of several non-intersecting sets, which can quickly merge and determine the set where elements are located. It has many applications, such as finding the number of connected components of an undirected graph. The most perfect application is to implement the kruskar algorithm to find the Minimum Spanning Tree.
And check the essence of the Set (that is, its three operations, combined with the implementation of the Code Template for understanding ):
1. make_set (x) initializes each element into a set.
After initialization, the father's day of each element is itself, and the ancestor node of each element is itself (which can also be changed based on the situation ).
/* Initialize the Set */void make_set (int x) {FATHER [x] = x; // The parent node specified based on the actual situation can change rank [x] = 0; // The initialization rank also varies according to the actual situation}
2. find_set (x) searches for the set where an element is located.
Find the set where an element is located. The essence is to find the ancestor of the set where the element is located! This is the final basis for checking and merging the set.
To determine whether two elements belong to the same set, you only need to check whether the ancestor of the set is the same.
Merging Two sets also makes the ancestor of one set become the ancestor of another set.
Optimization 1:
When you use and query sets for search, if the number of queries is large, you must use the simple search method to time out. For example, if there are 1 million elements and each query starts from 100th, this operation is 10 ^ 6. If the program requires 10 million queries, 10 ^ 13 is returned, there must be a problem.
This is a simple search code, suitable for situations with a small amount of data:
int findx(int x){ int r=x; while(parent[r] !=r) r=parent[r]; return r;}
The following describes the path compression method used to search for elements. The so-called path compression means that all elements passing through the path are directed to the parent node at the same time to facilitate the next search! In this way, the complexity will change to O (1) in the next search)
Int find (int x) // finds the set of X elements, and compresses the path {If (X! = Parent [x]) {parent [x] = find (parent [x]); // The compression path during backtracing} // search from the x node and find that all the nodes that have passed through the ancestor node point to the ancestor node return parent [X];}
The above is a recursive compression path, but recursive compression path may cause overflow stack, I used to re n times, next we will talk about non-recursive path compression:
Int find (int x) {int K, J, R; r = x; while (R! = Parent [R]) // find the following node r = parent [R]; // locate the following node and use R to record K = x; while (K! = R) // non-recursive path compression operation {J = parent [k]; // use J to store parent [k] parent node parent [k] = R; // parent [x] points to the following node K = J; // K moves to the parent node} return r; // returns the value of the root node}
3. Union (x, y) merges the two sets of X and Y.
It is easy to merge two non-intersecting sets:
Use find_set to find the ancestor of two sets and direct the ancestor of one set to the ancestor of another set.
. Each son points to the top ancestor, so that the query becomes O (1)
Optimization 2:
Union (x, y) Merge by rank (height)
That is, when merging, the set with fewer Heights will be merged into the set with more elements, so that the height of the merged tree willRelatively small.
void Union(int x, int y){ x = Find_Set(x); y = Find_Set(y); if (x == y) return; if (rank[x] > rank[y]) { father[y] = x; } else { if (rank[x] == rank[y]) { rank[y]++; } father[x] = y; }}
Send several poj questions:
Http: // 162.105.81.212/judgeonline/problem? Id = 1703
Http: // 162.105.81.212/judgeonline/problem? Id = 2421
Http: // 162.105.81.212/judgeonline/problem? Id = 2492
Http: // 162.105.81.212/judgeonline/problem? Id = 1861
Http: // 162.105.81.212/judgeonline/problem? Id = 1308
Http: // 162.105.81.212/judgeonline/problem? Id = 2524
Partially switched from http://www.cnblogs.com/vongang/