并查集--连通图相关

早上一番捣鼓,把以前丢失的onenote笔记找出来一部分.

看到并查集,大二做的笔记,现在已经毫无印象了

记得当时看的时候挺费劲,云里雾里的

现在再看一遍竟然毫无压力,一次读懂

其实确实挺简单的,没有那么高深.可能当时玩acm的时候太没自信了,看啥都难...

核心思想是用一个节点代表一块连通分支

可以通过路径压缩来减少以后查找的时间

非路径压缩递归写法:

int fFind(int i)
{
        if(pre[i]!=i) pre[i]=fFind(pre[i]);
        return pre[i];
}

路径压缩非递归写法:

int fFind(int i)
{
    int roooot=i;
    while(pre[roooot]!=roooot)
                roooot=pre[roooot];//寻根
    int tmp;
    while(pre[i]!=roooot)
        {
                tmp=pre[i];
                pre[i]=roooot;
                i=tmp;
        }//路径压缩
    return pre[i];
 }

适用于代码行数强迫症的一行写法:

int find(int x)
{
    return p[x]==x?x:p[x]=find(p[x]);
}

两个相关并查集交融的mix函数:

mix函数
void mix(int a,int b)
{
        int i=fFind(a),j=fFind(b);
        if(i!=j)
                pre[i]=j;
}
时间: 2024-12-09 18:55:47

并查集--连通图相关的相关文章

Network POJ - 3694(lca并查集+连通图求桥)

就是求出原先图中的桥的数量,在每一次询问时加入一条新边,求加入当前边后图中剩余的桥的数量 求出原先图中的桥的数量,然后减去新加入边的两端点之间的桥的数量,就是剩余桥的数量.. 用并查集把属于同一集合的放到一起(即两个点之间没有桥的) #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <algo

并查集间单个节点的转移(UVa 11987 Almost Union-Find)

从来没有这么艰难地完成一道算法题过!经过8次失败之后总算提交成功了!所以决定写一篇博文,对并查集的相关内容做一些总结. 普通并查集的操作无非是两种,find_set(x)即找到节点x所在的集合的代表节点,或者是union_set(x,y),即将x和y所在的两个集合合并起来.如下图所示,有左右两个并集 通常,我们会选用并查集中父节点为自己的元素作为这个并查集的代表,例如图中的节点a和节点e.那么,我们如何通过集合中的一个节点找到该节点所在集合的代表节点呢?其实很简单,例如上图中的d节点,它首先通过

并查集的简介

最近做题用到了并查集索性就把自己所掌握的相关知识总结一下. 并查集(union-find sets),CLRS上称为disjoint-set,是一组不相交的动态集合S1,S2,....Sk.它能够实现较快的合并和判断元素所在集合的操作,应用比较广泛,如其求无向图的连通分量个数,利用Kruskar算法求最小生成树等.它的主要操作为分为三部分: 1.初始化集合,Make_set().即将数组中每个元素单独划分成一个个集合,也就是每个元素的祖先节点(和父亲节点)是它本身.假设数组P用来存所有节点,则可

[HDOJ1232]畅通工程(并查集)

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1232 题目描述 Problem Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府"畅通工程"的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可).问最少还需要建设多少条道路? Input 测试输入包含若干测试用例.每个测试用例的第1行给出两个正整数,分别是城镇数目N ( <

[BZOJ3237][AHOI2013]连通图(分治并查集)

3237: [Ahoi2013]连通图 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1736  Solved: 655[Submit][Status][Discuss] Description Input Output Sample Input 4 5 1 2 2 3 3 4 4 1 2 4 3 1 5 2 2 3 2 1 2 Sample Output Connected Disconnected Connected HINT N<=1000

[CDQ分治 并查集] BZOJ 3237 [Ahoi2013]连通图

考虑CDQ分治 把这半边对后半边没有影响的操作做了 然后分治 用并查集维护 开个栈暴力还原 #include<cstdio> #include<cstdlib> using namespace std; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } re

图的遍历——A1013Battle over cities(25) 求需要添加多少条边才能构成连通图转化为找连通分量(可由DFS 和 并查集来找连通分量)

#include <bits/stdc++.h> #include <stdio.h> #include <stdlib.h> #include <queue> using namespace std; const int N = 1111; vector<int> G[N];//邻接表 bool vis[N];//标记顶点i是否被访问 int currentPoint;//当前需要删除的顶点编号 void dfs(int v){ if(v ==

今天做题做到了并查集相关的内容~简单介绍一下关于并查集的东西

就例如一个非常简单的题~ 有一堆人 其中某些人是朋友 有如下的规则 如果A和B是朋友 B和C是朋友 那么A和C也是朋友~ 最后我们有n次的查询 每次查询问其中两个人是不是朋友? 这个题我们就可以用到集合的思想~ 例如A和B是朋友 我们可以把A和B放到一个集合里~ C和D是朋友 我们就把C和D放到一个集合里~ 如图 (原谅只会人工画图的笨比) 但如果我们假设A和C也是好朋友 我们就把这两个集合合并起来~ 就是这个样子~我们对所有的“朋友对”进行这样的操作 就会把他们分到一个个集合里 这时候查找他们

零基础学并查集算法

并查集是我暑假从高手那里学到的一招,觉得真是太精妙的设计了.以前我无法解决的一类问题竟然可以用如此简单高效的方法搞定.不分享出来真是对不起party了.(party:我靠,关我嘛事啊?我跟你很熟么?) 来看一个实例,杭电1232畅通工程 首先在地图上给你若干个城镇,这些城镇都可以看作点,然后告诉你哪些对城镇之间是有道路直接相连的.最后要解决的是整幅图的连通性问题.比如随意给你两个点,让你判断它们是否连通,或者问你整幅图一共有几个连通分支,也就是被分成了几个互相独立的块.像畅通工程这题,问还需要修