And query the Set (disjoint-set forests)

Source: Internet
Author: User

Address: http://blog.csdn.net/ariesjzj/article/details/8001597

Here is an example of a simple application. Now that social networking websites are so popular, we suppose we want to know whether there is an indirect friend relationship between two people (A and B are friends, B and C are friends, And A and C are indirect friends ), what are the best methods? The query set is the valid data structure used for this type of query problem, just as its name (disjoint set). The query set is essentially a set and the elements of the set are trees, therefore, the query set actually represents a forest (disjoint-set forests ). It is characteristic that the members of each tree can be represented by the root node, So that you need to know whether the two nodes belong to the same element of the Set, as long as you see whether they have the same "representative ".

 

The logic is very simple. In fact, the original implementation will be slow, because the tree here does not guarantee a balance. In extreme cases, the tree will become a "bar" (each node has only one child ). Generally, two optimizations are used: Union by rank and path compression. The former makes the set as balanced as possible during the merge process, and the latter enables each node to direct directly to the root node, so that the query is completed at a constant time. Based on the two optimizations, the following is a textbook implementation:

int rank[100];int p[100];void makeSet(int x){p[x] = x;rank[x] = 0;}void unionSet(int x, int y){linkSet(findSet(x), findSet(y));}void linkSet(int x, int y){if (rank[x] > rank[y])  //union by rankp[y] = x;else {p[x] = y;if (rank[x] == rank[y])rank[y] = rank[y] + 1;}}int findSet(int x) {if (x != p[x])  // path compressionp[x] = findSet(p[x]);return p[x];}

 

The ancients said that they would not practice fake tricks. Let's take a look at what practical problems this seemingly simple data structure can solve:

Roadreconstruction (single round match 356 round 1-Division II, level three)

The questions are not surprising. They provide roads between cities, while some are good and some are broken. If they are broken, they also offer the price for repairs, ask how to connect all cities at the minimum cost. At first glance, it is the problem of the Minimum Spanning Tree in graph theory. Actually... We can use the minimal spanning tree solution, but here we try to use and query sets to solve the problem. Note that the following facts are used in the solution: At the beginning, N trees exist in the collection. Each tree has only one node and "represents" itself. After M-round merge, it becomes N-M. After n-1 round merge into one, all nodes in the original forest are fully connected.

#include <iostream>#include <fstream>#include <sstream>#include <vector>#include <algorithm>#include <string>#include <set>#include <map>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>using namespace std;typedef struct damaged_node {int cost;string id;int city1;int city2;} damaged_node;typedef struct non_damaged_node {int city1;int city2;} non_damaged_node;bool compare(const damaged_node& r1, const damaged_node& r2){return r1.cost < r2.cost;}int rank[100];int p[100];class RoadReconstruction {public:void makeSet(int x){p[x] = x;rank[x] = 0;}void unionSet(int x, int y){linkSet(findSet(x), findSet(y));}void linkSet(int x, int y){if (rank[x] > rank[y])p[y] = x;else {p[x] = y;if (rank[x] == rank[y])rank[y] = rank[y] + 1;}}int findSet(int x) {if (x != p[x])p[x] = findSet(p[x]);return p[x];}string selectReconstruction (vector <string> roads) {int n = roads.size();int i;int cno = 0;map<string, int> m;// map city name to no. in disjoint setvector<damaged_node> damaged;vector<non_damaged_node> non_damaged;vector<string> res;string ret = "";// parse the argumentsfor (i = 0; i < n; ++i) {string id, city1, city2;int cost = 0;istringstream iss(roads[i]);iss >> id >> city1 >> city2 >> cost;if (m.find(city1) == m.end())m[city1] = cno++;// generate unique id for each cityif (m.find(city2) == m.end())m[city2] = cno++;if (!cost){  // no cost, non damaged roadsnon_damaged_node t = {m[city1], m[city2]};non_damaged.push_back(t);} else {// damaged roadsdamaged_node t = {cost, id, m[city1], m[city2]};damaged.push_back(t);}}// init the disjoint setfor (i = 0; i < cno; ++i) {makeSet(i);}int cnt = 0;// reduce the disjoint set by considering non-damaged roadsfor (i = 0; i < non_damaged.size(); ++i) {int city1_no = non_damaged[i].city1;int city2_no = non_damaged[i].city2;findSet(city1_no);// update the parent, directly point to the representativefindSet(city2_no);if (p[city1_no] != p[city2_no]) {unionSet(city1_no, city2_no);cnt++;}}// try to reconstruct the damaged roads, in increasing order of costsort(damaged.begin(), damaged.end(), compare);for (i = 0; i < damaged.size(); ++i) {int city1_no = damaged[i].city1;int city2_no = damaged[i].city2;findSet(city1_no);findSet(city2_no);if (p[city1_no] != p[city2_no]) {unionSet(city1_no, city2_no);res.push_back(damaged[i].id);cnt++;}}if (cnt != cno - 1)return "IMPOSSIBLE";else {// all citys were merged into one.sort(res.begin(), res.end());for (i = 0; i < res.size(); ++i) {if (i)ret += " ";ret += res[i];}return ret;}}};

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.