· Disjoint-set algorithm notes

Disjoint-set

Disjoint-set I personally think that for processing a certain special data structure algorithms

This algorithm has two operations merge and query

  • Merge: can be high time will meet some of the data requirements of the subject combined in a set of
  • Query: the ability to time-sensitive queries whether a specified data exists in a collection being, or is calculated to meet the requirements of the subject the number of collection

So this is how the algorithm work?

Next we look at a few examples

  1. Relatives: disjoint-set of basic operational thinking ( point I jump QAQ )
  2. Triad gangs: Anti-set and complement thought ( point I jump QAQ )

1. relatives example

Luogu Portal

This is a very simple disjoint-set entry title, and here is used to check the operation of ideas about the set.

According meaning of the questions, if we can get B's relatives A, C B relatives, then ABC three relatives of each other, that ABC three nodes can be placed in the same collection which, for the convenience of presentation, we can this is considered a tree, a root node is a child, B and C are the a.

Disjoint-set .png

As a result, we will be able to take advantage of disjoint-set, there will be two nodes of relatives, were anchored in the query, as long as the use of a recursive , kept asking up until asked their root , the same as the root node, there is relatives.

However, there is a problem, so down a point to ask up again, it will spend a lot of time, then how can a high time to say it?

Here we need to do a disjoint-set optimized , so that it can be faster to calculate their root, I call it shrink point , all the points are related directly linked , that is, to construct a tree of depth 2, as shown in FIG.

Disjoint-set optimization .png

Thus, when a query can have direct access to their root a.

#include<stdio.h>
#include<algorithm>
int n,m,a,b,fa[10005];
int find(int x){   //查询函数
    if(fa[x]!=x) fa[x]=find(fa[x]);  //缩点:反复向上询问,询问到根节点才赋值
    return fa[x];
}
int main(){
    scanf("%d%d",&n,&m);
    for(register int i=1;i<=n;i++){fa[i]=i;} //初始化,开始时每个节点都是一个根节点
    for(register int i=1;i<=m;i++){
        scanf("%d%d",&a,&b);
        a=find(a);b=find(b);
        if(a!=b) fa[b]=fa[a];  //合并
    }
    int Q;
    scanf("%d",&Q);
    for(register int i=1;i<=Q;i++){
        scanf("%d%d",&a,&b);
        if(find(a)==find(b)) printf("Yes\n");  //根节点相同
        else printf("No\n");
    }
    return 0;
}

By This question, we can understand the basic operating principle disjoint-set, in fact, many of the basic codes in accordance with this title is also used as a template , but made some changes on this basis.

2. examples triad gangs

Luogu Portal

From the meaning of the questions, this question with a question on the big question frameworks, changes in place is

  • Seeking the number of collection
  • More out of the new concept, the enemy of my enemy is my friend

By the new concept will be extended to many new relationships, slightly rearranged, there is the following relationship

  • My friend's friend is my friend
  • My friend's enemy is my enemy
  • My enemy's enemy is my friend
  • My enemy's enemy is my friend

To be continued ......

Guess you like

Origin www.cnblogs.com/lightcoder/p/11418204.html