Check the set and use the set to check whether the graph has a ring (the minimum spanning tree that can be applied to Kruskal)

Source: Internet
Author: User

First, let's not introduce and check the concept of set. First, let's start with its application. It has two functions. The first is to determine whether a given node belongs to a specific set, which set does it belong. The second function is to merge two sets.

Given a group of data, such as: 1, 2, 3, 4, 5, 6, 7, 8, 9, they are a big set, however, we can also regard each of their numbers as an independent set, and then combine them to form a large set composed of all of them. Some people are very surprised that they are already a collection. Why do we need to organize them again? And if we want to find an element, can we just traverse it directly, time complexity is linear. People who are familiar with and query the set may immediately say: the two operations of using and querying the set: and querying, we can re-organize these numbers. When they have a certain logic,The search and merge operations can be completed in a time smaller than the linear value. What is used to represent and query the set? We apply the tree representation, but we do not create the node of the tree, instead, a parent number is used to indicate the ancestor of the element whose current index is index.

Example: I = 1, 2 ,..., 9. Parent [I] = I indicates that for a set with a single element, its root is itself. Next, traverse the array and create and query the set:

For 1, 2, their parent [1] = 1, parent [2] = 2, as long as the ancestor is different, it means they belong to different sets, then they should be merged, then let 1, 2 be used as the ancestor, and you can choose freely. I will tell you later, such a casual may cause the final query set to be equivalent to a common set, it has lost its advantage of searching quickly. After merging, there will be a set of two elements. When they are represented in the tree form, the ancestor is set to 1, and then the other two sets {1, 2} and {3} are merged }, first, it is very easy to determine whether they are in the same set. It is to determine whether the two sets are represented in the form of trees and whether they share the same ancestor. The first set has one ancestor, the ancestor of the second set is 3. Obviously, they are different, so they need to be merged. And so on until all individual sets are merged. The key to generating and querying a set equivalent to a common set is to select the root node when merging the two sets. If a is always a large set, B is always a small set, for example: {1, 2} and {3}, {1, 2, 3} and {4}, {1, 2, 3, 4} and {5}, if the root of a small set is always treated as the root of the merged set, then, when the query set is finally represented in the form of a tree, it is like a linked list. Therefore, a balance strategy is required to use the opposite method above: Use the root of the set with a large set of elements as the root after the two sets are merged. In this way, the height of the tree will decrease. At the same time, we also need to apply the path compression method to reduce the height of the tree.


Is and query the examples of the Union.

Provides basic information for searching and merging.Code:

 

Int find (int x) {int r = x; while (parents [R]! = R) r = parents [R]; int I = x, J; while (I! = R) {J = parents [I]; parents [I] = r; I = J;} return I ;}

For the first time may not understand this code, don't worry, give everyone a connection, read this side, should be able to understand the path compression: http://blog.csdn.net/dellaserss/article/details/7724401

 

And check the code of the collection:

 

 
Oid _ Union (int x, int y) {int FX = find (x); int FY = find (y); If (FX = FY) return; if (rank [x]> rank [y]) {parents [y] = x;} else {If (rank [x] = rank [y]) rank [y] ++; parents [x] = y ;}}


The rank array is set to reduce the height of the tree.

 

If you do not understand the above Code and do not understand it thoroughly, use an example to help you understand it. Use the application and check the set to determine whether a graph has a ring.


This graph has a ring that is known, but it is complicated to use code to judge it. First, we regard each vertex as an independent set {0}, {1}, {2 }, then it is stipulated that if two vertices are connected by edges, and if these two vertices do not belong to the same set, they will be combined to view the edge 0-1, merge the sets represented by these two vertices {0, 1} directly. Let 1 be the parent node and look at edge 1-2. They belong to different sets respectively, after merging the set, it is {1, 2}, and let 2 be the parent node. According to this logical relationship, the ancestor node of 0 is 2, and then watching the side 0-2, they belong to a set, because they share the same ancestor 2, which means that the 0-2 has been connected before the 0-2 side, if this edge is added, there will be two paths accessible from 0 to 2, indicating that there is a ring. The following code is provided:

 

# Include <iostream> # include <string> using namespace STD; typedef struct edge_s {int SRC; int DST;} edge_t; class graph {PRIVATE: int arc_num; int vex_num; int * parents; int * rank; edge_t * arcs; public: Graph (INT _ vex_num, int _ arc_num) {arc_num = _ arc_num; vex_num = _ vex_num; ARCs = new edge_t [arc_num]; Parents = new int [vex_num]; for (INT I = 0; I <vex_num; I ++) parents [I] = I; rank = new int [vex_num]; memset (rank, 0, vex_num * sizeof (INT ));}~ Graph () {Delete [] arcs; Delete [] parents; Delete [] rank;} void setedge (INT index, int SRC, int DST); int getarcnum (); int getvexnum (); int getedgesrc (INT index); int getedgedst (INT index); int find (int x); void _ Union (int x, int y );}; void graph: setedge (INT index, int SRC, int DST) {If (index <arc_num) {arcs [Index]. src = SRC; arcs [Index]. DST = DST ;}} int graph: getarcnum () {return arc_num;} int graph: getvexn Um () {return vex_num;} int graph: getedgesrc (INT index) {return arcs [Index]. SRC;} int graph: getedgedst (INT index) {return arcs [Index]. DST;} int graph: Find (int x) {int r = x; while (parents [R]! = R) r = parents [R]; int I = x, J; while (I! = R) {J = parents [I]; parents [I] = r; I = J;} return I;} void graph: _ Union (INT X, int y) {int FX = find (x); int FY = find (y); If (FX = FY) return; If (rank [x]> rank [y]) {parents [y] = x;} else {If (rank [x] = rank [y]) rank [y] ++; parents [x] = y ;}} bool iscontaincycle (graph & G) {int I; for (I = 0; I <G. getarcnum (); I ++) {int FX = G. find (G. getedgesrc (I); int FY = G. find (G. getedgedst (I); If (FX = FY) return true; G. _ Union (FX, FY);} return false;} int main (INT argc, char * argv []) {graph G = graph (3, 3); G. setedge (0, 0, 1); G. setedge (1, 1, 2); G. setedge (2, 0, 2); If (iscontaincycle (G) cout <"yes" <Endl; elsecout <"Non" <Endl; cin. get (); Return 0 ;}

 


 

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.