And query set (used for the data structure of the non-intersecting set)

Source: Internet
Author: User
Check the set and check the set to maintain a group of dynamic sets S = {S1, S2 ,..., SK }. each set is represented by a Member. And query the essence of the Set (that is, its three operations): each element in the set is represented by an object, and X indicates an object make-set (X) create a new set, and its unique member (thus its representative) is X. Because each set is not intersecting, it is required that X does not appear in other sets. After initialization, the father's day of each element is itself, and the ancestor node of each element is also its sample code.
# Include <stdio. h> # include <stdlib. h> int father [1001]; int main () {int n, m, I, X, Y; while (scanf ("% d \ n", & N )! = EOF & n! = 0) {// initialize and query the set for (I = 1; I <= N; I ++) {FATHER [I] = I ;}}}
Union (x, y) combines dynamic sets that contain X and Y (for example, SX and SY) into a new set (that is, the union of these two sets ). it is easy to merge two non-intersecting sets: Use Find-set to find the ancestor of the Two Sets and direct the ancestor of one set to the ancestor of the other set. Sample Code
void union_set(int x, int y){int fx, fy;if (fx != fy) {fx = find_set(x);fy = find_set(y);}father[fx] = fy;}
Find-set (x) returns a pointer pointing to the (unique) set containing X, which represents the collection where an element is located. The essence is to find the ancestor of the set where this 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
Sample Code
int find_set(int x){while (father[x] != x) {x = father[x];}return x;}
Reference
Description: Mr Wang wants some boys to help him with a project. because the project is rather complex, the more boys come, the better it will be. of course there are certain requirements. mr Wang selected a room big enough to hold the boys. the boy who are not been chosen has to leave the room immediately. there are 10000000 boys in the room numbered from 1 to 10000000 at the very beginning. after Mr Wang's selection any two of them who are still in this room shoshould be friends (direct or indirect), or there is only one boy left. given all the direct friend-pairs, you shoshould decide the best way. input: the first line of the input contains an integer N (0 ≤ n ≤0 ≤ 100 000)-the number of direct friend-pairs. the following n lines each contains a pair of numbers a and B separated by a single space that suggests a and B are direct friends. (A = B, 1 = A, B = 10000000) Output: the output in one line contains exactly one integer equals to the maximum number of boys Mr Wang may keep. sample input: 41 23 45 61 641 23 45 67 8 sample output: 42

AC code

# Include <stdio. h> # include <stdlib. h> int father [10000001]; int number [10000001]; int Max; int find_set (int x); void union_set (int x, int y); int main () {int I, n, x, y; while (scanf ("% d", & N )! = EOF) {// initialize the set for (I = 1; I <= 10000001; I ++) {FATHER [I] = I; number [I] = 1 ;} // merge and query Set max = 1; for (I = 0; I <n; I ++) {scanf ("% d", & X, & Y); union_set (x, y) ;}// output result printf ("% d \ n", max) ;}return 0 ;}int find_set (int x) {While (X! = Father [x]) {x = Father [X];} return X;} void union_set (int x, int y) {int FX, FY; FX = find_set (x); FY = find_set (y); If (FX! = FY) {number [FY] + = number [FX]; number [FX] = number [FY]; father [FX] = FY; if (number [FY]> MAX) {max = number [FY] ;}}

In another faster implementation of the non-intersecting sets, query set optimization uses a root tree to represent the set. each node in the tree contains a member of the Set, and each tree represents a set. By introducing two heuristic strategies: "merge by Rank" and "path compression ", we can obtain the currently known Fastest Non-intersecting set data structure in a progressive sense. The data structure is merged by rank, which is similar to the weighted merge heuristic method we use for linked lists. The idea is to direct the root of a tree with fewer nodes to the root of a tree with more nodes. Instead of explicitly recording the size of the subtree with each node as the root, we use a method that simplifies the analysis. For each node, rank indicates an upper bound of the node height. In rank-based merge, the root with smaller rank points to the implementation code of rank-based merge with larger rank in the union operation:

// Initialize and query the number group for (I = 1; I <= N; I ++) {FATHER [I] = I; rank [I] = 1 ;} paths = (struct path *) malloc (sizeof (struct path) * m); // receiving side for (I = 0; I <m; I ++) {scanf ("% d", & Paths [I]. u, & Paths [I]. v, & Paths [I]. len);} qsort (paths, M, sizeof (paths [0]), compare); // Kruskal calculates the Minimum Spanning Tree for (I = MST = COUNT = 0; I <m; I ++) {u = find_set (paths [I]. u); V = find_set (paths [I]. v); If (u! = V) {// optimize if (rank [u] <rank [v]) {FATHER [u] = V;} else {FATHER [v] = u; if (rank [u] = rank [v]) {rank [v] ++ ;}} MST + = paths [I]. len; // number of records to determine the connectivity count ++ ;}}

Path compression is performed in the find-set operation. This heuristic policy is used to direct each node in the search path to the root node. Path compression does not change the node rank. This very simple and effective find-set process with path compression is also quite simple:

int find_set(int x){int parent;if (x == father[x]) {return x;} parent = find_set(father[x]);father[x] = parent;return parent;}

The find-set process is a two-way method (two-pass method ):

  • The first step is to go up along the search path until you find the root
  • The second step is to drop along the search path to update each node and direct it to the root node.
The following figure shows a query set + Kruskal Algorithm for the minimum spanning tree. The "path compression" optimization algorithm must be used in the find-set operation. Otherwise, the Tle problem occurs.
Description: there are now n isolated islands, which start from 1 to n, and there are m roads (roads are bidirectional. If multiple roads are connected to island I, j. Select the shortest path.) Find the minimum length of the road that can connect all islands. Input: multiple groups of data are input. Input N (1 <= n <= 1000) and M (0 <= m <= 10000) in the first row of each group ). Then, in Row M, enter a path I j d (0 <= d <= 1000), (I, j indicates the island number, and D indicates the road length ). Output: Output a line of input to each group. If the output can be connected, the output can be connected to the minimum road length of all islands. Otherwise, output the string "no ". Sample input: 3 51 2 21 2 12 3 51 3 33 1 24 21 2 33 4 1 sample output: 3NO

AC code

# Include <stdio. h> # include <stdlib. h> struct path {int U, V, Len ;};# define Max 1005 int father [Max]; int rank [Max]; int compare (const void * P, const void * q) {const struct path * A = P; const struct path * B = Q; return a-> len-B-> Len;} int find_set (INT X) {int root; If (x = Father [x]) {return X;} root = find_set (father [x]); father [x] = root; return root ;} int main () {int I, n, m, U, V, MST, Coun T; struct path * paths; while (scanf ("% d", & N, & M )! = EOF) {// initialize and check the number of groups for (I = 1; I <= N; I ++) {FATHER [I] = I; rank [I] = 1;} paths = (struct path *) malloc (sizeof (struct path) * m); // receiving side for (I = 0; I <m; I ++) {scanf ("% d", & Paths [I]. u, & Paths [I]. v, & Paths [I]. len);} qsort (paths, M, sizeof (paths [0]), compare); // Kruskal calculates the Minimum Spanning Tree for (I = MST = COUNT = 0; I <m; I ++) {u = find_set (paths [I]. u); V = find_set (paths [I]. v); If (u! = V) {If (rank [u] <rank [v]) {FATHER [u] = V;} else {FATHER [v] = u; if (rank [u] = rank [v]) {rank [v] ++ ;}} MST + = paths [I]. len; // number of records to determine the connectivity count ++ ;}// print the output if (count <n-1) {printf ("NO \ n ");} else {printf ("% d \ n", MST);} Free (paths);} return 0 ;} /*************************************** * *********************** problem: 1347 User: wangzhengyi language: C result: accepted time: 920 MS memory: 1156 kb ************************************** **************************/

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.