zoukankan      html  css  js  c++  java
  • 数据结构——并查集

    并查集

    特点

    根节点的父节点是自己

    材料准备

    fa[x]表示的是x的父节点。

    操作

    找到根节点

    一般路径

    • 借用递归(根节点的父节点是自己
    int find(int x)
    {
          if(fa[x]==x)return x;
          else return find(fa[x]);
    }
    
    • 缩行
    int find(int x)
    {
         return fa[x]==x?x:find(fa[x]);
    }
    

    路径压缩(实为合并)

    int find(int x)
    {
        if(fa[x]==x)
          return x;
        else{
             fa[x]= find(fa[x]);//如果有x有多辈祖宗,也会被搞成只剩一辈
             return fa[x];
        }
    }
    
    • 缩行
    int find(int x)
    {
         return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    

    合并

    • 令i的根节点的父节点变成j
    void merge(int i,int j)
    {
        fa[find(i)] = find(j);
    }
    

    P1111 修复公路

    题目背景

    AA地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车。政府派人修复这些公路。

    题目描述

    给出A地区的村庄数NN,和公路数MM,公路是双向的。并告诉你每条公路的连着哪两个村庄,并告诉你什么时候能修完这条公路。问最早什么时候任意两个村庄能够通车,即最早什么时候任意两条村庄都存在至少一条修复完成的道路(可以由多条公路连成一条道路)

    输入格式

    第11行两个正整数N,MN,M

    下面MM行,每行33个正整数x, y, tx,y,t,告诉你这条公路连着x,yx,y两个村庄,在时间t时能修复完成这条公路。

    输出格式

    如果全部公路修复完毕仍然存在两个村庄无法通车,则输出-1−1,否则输出最早什么时候任意两个村庄能够通车。

    思路

    • 时间从小到大(排序,模拟)

    • 并查集(所有结点指向同一结点时结束)

      • 并查集初始化(所有点都指向自身)

      • 如果fx和fy的头节点不同的话

      • f[fx]=fyf[fy]=fx的差别

        • f[fx]=fy:fx的头节点是fy,且经过路径压缩后,fx的子节点都会归并到fy的名下。

        • f[fy]=fx:fy的头节点是fx,且经过路径压缩后,fy的子节点都会归并到fx的名下。

        • 所以两者的差别仅是合并后点的父节点的暂时不同。

    • 代码

     int find(int x){return f[x]==x?x:f[x]=find(f[x])}
    
    • f[x]=find(f[x])表示的是以x的父节点f[x]为根据找到最终的父节点,并将最终的父节点更新为原本的父节点。

    • 注意:每进行一次合并就是意味着孤立的点减少一。注意:合并的前提是这两个点最终的父节点是不同的。

    参考

    洛谷题解

    知乎并查集

  • 相关阅读:
    2019年面试题1
    面试题
    vsftp多个用户公享同一个文件,但是权限不同
    centos7搭建ftp
    安装v2ra y
    centos7安装lamp
    日升昌面试题
    一些插件
    面试被怼集(字节跳动篇)
    TOMCAT原理详解及请求过程(转载)
  • 原文地址:https://www.cnblogs.com/BeautifulWater/p/14569353.html
Copyright © 2011-2022 走看看