And query the set to get started.
<This article is not completely original>
And check the set definition
The query set is a tree-type data structure used to deal with the merge and query problems of some Disjoint Sets. Forest is often used.
Set is to make each element constitute a single element set, that is, to merge the sets of elements belonging to the same group in a certain order.
Query the purpose of the Set
① Maintain the connectivity of an undirected graph. When judging n points and m edges, the minimum number of edges can be connected to all vertices.
② Judge whether edge adding between two points will generate a ring in an undirected graph. (The minimal spanning tree is used by cruise cart)
③ Maintain the set and other operations.
Query Set Operations
As the name implies, the so-called parallel query set provides two operations:
① Merge two sets.
② Query: Check whether two elements are in a set.
Principle of querying Sets
Let's take a look at a little story.
There are thousands of heroes scattered across the world. They have no proper profession. They walk around with a sword all day. If they meet people who are not in the same way as themselves, they will inevitably fight. However, one of the advantages of the heroes is to be loyal and never beat friends of their own. They also believe that "friends of friends are my friends". As long as they can be connected by friends, no matter how many turns they turn, they all think they are their own people. In this way, the rivers and lakes form a community, which is connected by the relationship of friends between the two. People who are not in the same community cannot connect with friends in any way, so they can rest assured that they will die. But how do two people who are not familiar with each other determine whether they belong to a circle of friends?
We can cite a famous person in every circle of friends as a representative of this circle, in this way, each circle can name "The Friends of Zidane" and "The Friends of Ronaldo "...... The two can determine the relationship between the enemy and friends as long as they match each other's team leaders.
But there is still a problem. The heroes only know who their friends are. Many people do not know the team leader at all. They need to determine who their team leader is, "Are you the captain? Are you the captain ?" In this way, the captain's face is lost, and the efficiency is too low, and may fall into an infinite loop. The captain ordered a new team. All members in the team adopt a hierarchical system to form a tree structure. Our team leader is the root node. Below are level 2 members and Level 3 members respectively. Everyone just needs to remember who their superiors are. When judging the enemy and friends, you only need to raise the question layer by layer until the highest level, you can determine who the captain is in a short time. We only care about whether two people are connected. It doesn't matter how they are connected, how they are connected, and what the internal structure of each circle is, or even who the team leader is. So we can let the Captain reteam at will, as long as there is no mistake in the relationship between friends and enemies. As a result, the school came into being.
Let's take a look at and check the implementation of the Set:
-> Int pre [1000]; this array records the superiors of each hero. Heroes start from 1 or 0 (based on the question)
-> Pre [15] = 3 indicates that the superior of the 15th Daxia is the 3rd Daxia.
-> If a superior is himself, it means that he is the manager.
-> There are also independent leaders. For example, Ouyang Feng, his superiors are his own.
Everyone recognizes their superiors only.
For example, Hu qingniu only knows that his superior is Yang Zuo. Who is Zhang Wuji? No! If you want to know who your boss is, you can only query it at the level.
The find function is used by the manager. It makes sense again (the path compression algorithm does not matter, but will be discussed later ).
Int find (int r) // find the head of my (r) {while (pre [r]! = R) // If r's superiors are not r's own (that is to say, the man he finds is not the manager) r = pre [r]; // r goes on to find his superiors, until the head is found. Return r; // The Head of the game is driving ~~~}
Let's take a look at the join function, that is, to connect a line between the two points, so that all the points of the original two sections can be interconnected. This is easy to do on the graph. Just draw a line. But now we use the lookup set to describe the situation in the martial arts. There is only one pre [] array. How can we implement this? Let's give an example of the current situation in martial arts. Xiao Zhu's Monk and Zhou xiaomuo's MM are two people I like very much. Their ultimate boss is Xuan cifang's and the extinct Division's, which are obviously two camps. If I don't want them to fight each other, I will say to them, "You Two Are pulling a hook, be a good friend ." They agreed on my face. This can be done together with Xiao Ke, And the whole Shaolin and Emei can no longer fight. How can we implement such a major change? How many changes do we need? In fact, it is very simple. I said to Xuan cifangzhang: "Master, please change your superiors to an extinct teacher. In this way, the ultimate boss of all the original members of the two schools is the teacher, so I still play a ball! We only care about connectivity, and the internal structure of the school doesn't matter ." Xuan ciyi certainly got angry: "I rely on it. Why did I become her employee? Why didn't I turn it back? I protest !" The protest is invalid. It was arranged by heaven. In any case, the effect is the same for anyone who joins the project. What does this function mean?
Void join (int x, int y) // if I want to be a friend of {int fx = find (x), fy = find (y ); // xuzhu's boss is Xuan CI. if MM's boss is extinct if (fx! = Fy) // Xuan Ci and the extinction are obviously not the same person pre [fx] = fy; // Xuan Ci had to submit his work as a teacher}
An Optimization of merge operations:
If one tree is forced to be merged in this way without being judged, it is easy to create an extremely unbalanced tree, just like
According to the previous example, Xuan Ci is very enthusiastic about why I should be his employee. It is clear that I have more people than her, but I cannot accept it, in order to calm down the anger and laziness of the Abbot, god finally added a rule that the number of people in the door was less than the number of people in the hands, and the number of people was the same. Finally, everyone is satisfied with this, which ensures that the tree can be maintained in a relatively balanced degree.
(Note: When merging, you must know who is merged !)
<Merge by rank>: merge a set with fewer elements into a set with more elements. In this way, the height of the merged tree is relatively small.
// Rank [] is initialized to 1, representing the number of people under void join (int x, int y) // if I want to make friends {int fx = find (x) and fy = find (y) between weizhu and Zhou; // Xuan Ci is the boss of fuzhu, if (fx! = Fy) // Xuan Ci and extinct are obviously not the same person {if (rank [fx]> = rank [fy]) // The two started to have more members than their peers {pre [fy] = fx; // Xuan Ci had more people and became the boss rank [fx] + = rank [fy]; // all the extinct men belong to Xuan CI} else {pre [fx] = fy; // There are many extinct people and become the boss rank [fy] + = rank [fx]; // all of Xuan CI's men are extinct }}}
The number of layers in the tree can also be merged by rank, so that the number of queries can be kept inlogBut if path compression is used at the same time, it is difficult to maintain the number of layers of the tree, so here I use the number of child nodes for maintenance.
Let's take a look at the path compression algorithm.
The process of building the school is to use the join function to connect two people, who are totally random. I can't predict what kind of tree structure will become. It is also possible to have a sn. In this way, the search efficiency will be relatively low. The ideal situation is that all direct superiors are in charge, and there are two levels of structure in total. You only need to find the manager once. Even if it cannot be done completely, it is best to approach it as close as possible. In this way, the path compression algorithm is generated. Imagine a scenario where two heroes meet each other and want to know if they can beat each other. So I quickly called my superiors and asked, "Are you the manager ?" The superior said, "I am not, who is my superior and who is, please ask him ." All the way down, the boss of the two was originally Cao gonggong of the East factory. "Oh, I used to be one of my own. I was rude. In the next three camps, there were six groups of white gourd dolls !" "Fortunately, we are lucky to have a bunch of fairy dog tails and flowers in the ninth camp !" The two went drinking with pleasure. "Wait a moment. Please leave the two students for a while. There are still some unfinished work !" I want to stop them. "Oh, by the way, we still need to compress the path ." The two were awakened. White-faced huluwa called his parent six leaders: "I have checked the team lead. Cao gonggong is the director of his study couple. It's better for me to work together and worship them under Cao gonggong. the province's level is too low, so I will find the manager in the future ." "Well, it makes sense ." The white-faced gourd doll then called the three battalion leaders who just visited ...... The fairy dog's tail and flower have done the same thing. In this way, all the involved figures in the query are under the direct leadership of Cao gonggong. Each query is optimized, so the number of layers of the school tree remains relatively low. Both query and path compression are recursive and non-recursive methods. recursive is easy to write and non-recursive is easy to understand. When to use that depends on the situation.
// Non-recursive writing int find (int r) {int p1 = r, p2; // p1 Save the prawns while (r! = Pre [r]) r = pre [r]; // r finally stores the head while (pre [p1]! = R) // If the prawn himself is not the head r {p2 = pre [p1]; // Save the superior pre [p1] = r of the prawn; // first tell the prawn who owns the door p1 = p2; // then ask the superior of the prawn to tell him who owns the door} return r ;} // recursively write int find (int r) {if (pre [r]! = R) pre [r] = find (pre [r]); // recursively assigned values of the retrieved ancestor, connect every node that passes this search to the ancestor node directly. return pre [r];}
And check the water problem Trainer: http://www.cnblogs.com/kannyi/p/8507835.html