zoukankan      html  css  js  c++  java
  • 并查集 笔记与思路整理

    算是非常基础的内容了,之前写到Kruskal的时候突然想起还没整理过。

    其实就想存个板子

    并查集是一种树型的数据结构,用于处理一些集合(只能是不交集)。

    “感性理解”一下就是把一堆东西分成若干堆,每个东西都在且仅在其中一堆里。

    具体实现的话利用一个father数组,指向该元素的父亲节点。初始时所有元素的father均为它自己,表示每个元素均各自在自己的集合里。若两个元素在同一个集合中,它们的祖先就为同一个。

    主要是两个函数:join和find。

    先说一下find:

    int find(int x) {
        if(father[x]!=x) father[x] = Find(father[x);
        return father[x];
    }

    很好理解,如果x是自己的父亲,它就是自己集合的根节点,否则就逐层查询到根节点为止(顺便路径压缩——把集合中的点都直接连在根节点下)。这个函数主要是用来通过看两个元素的祖先是否一致,判断两个元素是否在同一个集合中。

     然后是join:

    void Join(int x, int y){
        int fx = Find(x), fy = join(y);
        if(fx != fy) father[fy] = fx;
        return;
    }

    这里需要想象一下,假如要把两个很大的集合合并起来,最简单的操作就是直接把一个集合的根节点并到另一个集合下。(至于结构会很混乱嘛……下次Find的时候再整理就行了)

    代码实现:

    #include <bits/stdc++.h>
    using namespace std;
    int father[10010];
    int Find(int x) {
        if(father[x]!=x) father[x]=Find(father[x]);
        return father[x];
    }
    void Join(int x, int y){
        int fx = Find(x), fy = join(y);
        if(fx != fy) father[fy] = fx;
        return;
    }
    int main() {
        for(int i=1; i<=10000; i++) father[i]=i;
        int n, m, x, y;
        scanf("%d %d", &n, &m);
        while(m--) {
            scanf("%d %d",&x,&y);
            Join(x, y);
        }
        int p;
        scanf("%d", &p);
        while(p--) {
            scanf("%d %d",&x,&y);
            if(Find(x) != Find(y)) printf("F
    ");
            else printf("T
    ");
        }
        return 0;
    }
  • 相关阅读:
    silverlight 网站 iis发布
    使用PerfView诊断.Net GC的问题
    七种方法实现单例模式
    java多线程的学习之路(二)
    java多线程的学习之路(一)
    几种特殊的二叉树
    解析json字符串,把json字符串转换成Java对象
    KMP算法的理解
    常用 Git 命令清单
    Jquery.cookie.js 源码和使用方法
  • 原文地址:https://www.cnblogs.com/miserweyte/p/11408458.html
Copyright © 2011-2022 走看看