Query Union-find

Source: Internet
Author: User

What can be done in the query set?

1. connect two objects;

2. query whether two objects are in a collection, or whether the two objects are connected together.

 

What applications does the query set have?

1. percolation problems,

2. Number of connected subgraphs in an undirected graph

3. Recent public ancestor Problems

4. Kruskal minimal spanning tree

5. Social Networks

 

Check the data structure of the dataset:

A query set is a tree-like data structure that processes the merge and query operations on non-intersecting sets.

Common heuristic policies for querying sets: path compression, merge by rank (or merge by the number of set elements)

Path compression aims to accelerate the search efficiency and make the tree even possible.

Merge by rank (or merge by the number of elements in the Set) is a weighted merge policy that allows the root containing fewer nodes to point to the root of more nodes.

Initialization: Each element itself represents a set

void init(int n) {    for (int i = 0; i <= n; i++) {        fa[i] = i;        rank[i] = 0;    }}

Search: Find the top element of the current set and compress the path during the search process. The following are three search methods. The first method is to Recursively search and compress the path, the second is to explicitly search for and compress, the third is to traverse twice, the first is to find the root, and the second is to compress the path.

int find(int x) {    return (x==fa[x]) ? x : (fa[x]=find(fa[x]));}int find(int x) {    while (x != fa[x]) {        fa[x] = fa[fa[x]];        x = fa[x];    }    return x;}int find(int x) {    int root = x;    while (root != fa[root]) root = fa[root];        while (x != fa[x]) {         fa[x] = root;        x = fa[x];    }    retur root;}

Merge: The merge operation combines the set where p and q are located, and adopts the heuristic strategy of rank-based merge.

void unionSet(int p, int q) {    int fp = find(p);    int fq = find(q);    if (fp == fq)    return;    if (rank[fp] < rank[fq]) fa[fp] = fq;    else {        fa[fq] = fp;        if (rank[fp] == rank[fq])    rank[fp]++;    }}

Set relationship: determines whether p and q are in the same set

bool connected(int p, int q) {    return find(p) == find(q);}

The basic merge and query set structure with path compression is similar, and the query set complexity analysis is more complex, when M Union-find operations on n objects, the time complexity is about N + MLG * n.

 

Poj 1182 food chain

For typical types and query sets, refer to the ideas in challenge programming. For animal X, we use X to represent a type, and x + n to represent B type, respectively, X + 2n indicates the C type.

I mainly think about how to determine the conflict between the current words and the previous words.

For input 1, x, and Y, this statement indicates that X and Y are of the same type. If a of X is of the same type as B of y, or the type of X and the C type of Y are a set. This sentence is a lie. Otherwise, we need to merge the type of X and Y, the B type of X and Y, and the C type of X and Y.

if (connected(x, y+n) || connected(x, y+2*n)) {    ans++;} else {    unionSet(x, y);    unionSet(x+n, y+n);    unionSet(x+2*n, y+2*n);}

For input 2, X, and Y, this statement indicates that X eats Y. If the type of X is a set with the type of Y, the similar set cannot prey on it. This is a lie. If the type of X is a set with the C type of Y, it indicates that y prey on X, which is also incorrect. In other cases, we can combine the type of X with the B type of Y, the B type of X with the C type of Y, and the C type of X with the type of Y.

if (connected(x, y) || connected(x, y+2*n)) {    ans++;} else {    unionSet(x, y+n);    unionSet(x+n, y+2*n);    unionSet(x+2*n, y);}

Full: https://gist.github.com/Lee656/edc34d790461afae190e#file-poj_1182-cpp

BTW: This is a single case.

 

Poj 2524 ubiquitous religions

Each element is initially a set, which combines the input p and q sets, and finally outputs the number of sets. Use a component variable to maintain the number of sets. The initial number is n. When two p and q are not merged in the same set, the number of component values minus 1, finally, component stores the number of sets.

Full: https://gist.github.com/Lee656/edc34d790461afae190e#file-poj_2524-cpp

 

Poj 1611 the suspects

The meaning of the question is to merge the set continuously, and finally output the size of the set where 0 is located. Here we can use the heuristic rule based on the number of elements in the Set mentioned above to merge, and finally output the number of elements in the set at the top of the set where 0 is located, which is the answer to the question. After merging all the sets, we can determine whether to find (0) = find (other) for all except 0, in this way, the number of elements in the set where 0 is located is counted.

Full: https://gist.github.com/Lee656/edc34d790461afae190e#file-poj_1611-cpp

 

Poj 1456 supermarket

The topic describes P and D for each product, which respectively represent the value of the product and the end time of the product to be sold.

Then we can have a greedy strategy to sort commodities by value from large to small. If values are the same, they are sorted by time from large to small, the larger the value of the product we want to obtain, the better. The longer the deadline, the more space we choose will not conflict with other time periods. Use a d [] to mark the cutoff time that has been used up. If it is used up, we will find the unavailable cutoff time before the cutoff time. If it is not used up, we will use it directly.

Full: https://gist.github.com/Lee656/edc34d790461afae190e#file-poj_1456v2-cpp

 

So what is the relationship between this question and the query set? When we find that a certain cutoff time has been used up, we go forward to the for loop to enumerate the search, and there is no used cutoff time. Here we will go into the query set. Replace the for loop with the and query set to find and merge the used current vertex I with its previous vertex I-1, when we need to know the deadline for unused I, we only need Pos = find (I. time.

Full: https://gist.github.com/Lee656/edc34d790461afae190e#file-poj_1456v1-cpp

 

Poj 1703 find them, catch them

Similar to the type of the food chain and check the collection. For someone X, use X to represent his gang, and x + n to represent his rival gang.

If operations on D, X, Y, X, and y belong to different gangs, the target gangs of X and Y are consortium, Union (X, Y + n ), x's rival gangs and Y's gangs are consortium, Union (x + N, Y ). Enemies of the enemy are friends.

For operations A, X, Y, determine whether X and Y are in the same gang. If find (x) = find (Y), it is the same gang. If find (x) = find (Y + n), it is a rival gang. Others are unknown.

Full: https://gist.github.com/Lee656/edc34d790461afae190e#file-poj_1703-cpp

 

Poj 1988 cube stacking

This topic describes n stacks. Initially, each stack contains 1-N blocks and two operations are defined. The first operation is m x Y, move the stack where X is located to the top of the stack where Y is located, and the other operation is c x. How many squares are there under X currently.

The merge query set is used. For m x Y operations, the stack where X is located is placed on the stack where Y is located. We need to merge the set where X and Y are located, point the set where Y is located to the set where X is located. But how do we obtain the number of squares under X when performing a query on the C x operation? If we record the current vertex and check the distance from the top root of the Set, if we know the current vertex and check the number of set elements, the size is large, then the difference between the two is reduced by 1 to get the result of the C x operation.

How to maintain the distance from the point to the root, we use the Array up [], up [x] to indicate the distance from X to the root of the set and check the root of the set. At first, each of them is the root of the tree, then up [] = 0. When merging, We append a set Y to the X set. Then, the root distance from the initial X set to itself is 0, now that the root points to the root of Y, It is corrected to the size of the set where Y is located, that is, SZ [FY]. then, update the size of the collection where Y is located. sz [FY] + = SZ [FX]

Void union_set (int p, int q) {// place the stack where p is located on the stack where Q is located. Int fp = find (p); int FQ = find (Q ); if (FP = FQ) return; Fa [FQ] = FP; // FQ points to FP up [FQ] + = SZ [FP]; // update the root node of Q to the root node of the new P. The distance between SZ [FP] + = SZ [FQ]; // update the number of root nodes of p}

Here, we only modified the value of the root up of X, but the value of the up of the node element under the root of X has not been updated yet. The update in this step is in the find operation, while compressing the path, update the distance from the current point to the root point.

Int find (int x) {int TMP = Fa [X]; If (x = Fa [x]) return X; fa [x] = find (Fa [x]); up [x] + = up [TMP]; // returns Fa [x] from the current point to the root;}

Here we can also write it as mentioned above. First find the root, then compress the path + correct the value of up.

Figure:

Full: https://gist.github.com/Lee656/edc34d790461afae190e#file-poj_1988-cpp

 

 

What is it a tree in poj 1038?

The answer to the question is very simple. I give a lot of sides and finally determine whether a tree can constitute a tree. For the question, the tree does not have a ring and only one tree can exist.

It is simple to check whether the two vertices are already in the same set when adding edge. Then, judge whether all vertices are in a set and cannot constitute a forest.

Full: https://gist.github.com/Lee656/edc34d790461afae190e#file-poj_1038-cpp

 

Poj 2492 a Bugs life

The idea of solving this problem is similar to that of poj1703. Each worm is divided into two types: the male and the male.

Full: https://gist.github.com/Lee656/edc34d790461afae190e#file-poj_2492-cpp

 

Poj 2236 Wireless Network

Bare and check set. You need to pre-process the computer adjacent table within d ^ 2, and then add the open computer together when performing the query operation.

Full: https://gist.github.com/Lee656/edc34d790461afae190e#file-poj_2236-cpp

 

Poj 1962 coporative Network

The idea and practice of this question are the same as those of poj1988. I won't go into details here,

Full: https://gist.github.com/Lee656/edc34d790461afae190e#file-poj_1962-cpp

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.