求最小环 —— 并查集 与 Floyd
对于一个图,如何求出其中的最小环(不包括一元环)?
很显然,对于一个无向图,每一条边都是一个二元环;对于有向图,可以考虑从每一个点出发,用DFS求出它到自己的距离,如果遍历了$N$个点仍未便利到自己,则该点不在环中。但是这样做的复杂度非常感人……如果没有分析错的话最坏应该是$O(n^2 m)$
可以考虑有一些优化, 对于一个点,如果它在一个环中,那么它在该环上dfs过的点一定在环中。在回溯一个点的过程中,如果搜到环,那么在搜下一个点的时候就不清空他们的标记数组。对于搜不到环的点,它的入度一定为一,如果不为一,那么删除它入边所连的入度为零的点后入度为零。所以可以预处理,删除入度为零的点和它所连的边(如果后面还有用就标记),然后再按照上述方式dfs,时间复杂度为$O(nm)$
但是对于稠密图,复杂度还是太高,甚至高过$O(n^3)$,这听起来是不是有些耳熟? 没错,Floyd。
用 $k$ 作为当前搜索点,不断求出其它点的最短路径和路经所在环长,即
$dis[i][j] = std::max(dis[i][j], dis[i][k], dis[j][k]), ans = std::max(ans, dis[i][j]+G[k][i]+G[j][k]); // G[][] 为邻接矩阵$
时间复杂度为 $O(N^3)$
当然,在$N>1000$的稠密图中,这种方法的复杂度依然很感人。
由于连边的关系也可以看作是树中“父与子”的关系,则可以使用并查集,通过路径压缩求出在某一图中的环,若存在两个连边的点在同一并查集中,那么一定有环,环的权值为两点到祖先的权值和加1。
为什么这样是对的呢? 在一个路径已经被压缩的树中,任意两节点在图中一定相连,当某一点的父节点成为该点的子节点时,该点一定在环上。只要没有重边,那么该方法一定适用。
Floyd 代码:
int G[N][N], dis[N][N];
int main(){
for(int k = ; k <= n; k++){
for(int i=;i<=k-;i++)
for(int j=i+;j<=k-;j++)
ans = std::max(ans, dis[i][j]+G[k][i]+G[k][j]);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
dis[i][j] = std::max(dis[i][j], G[i][k]+G[k][j]);
}
//...
return ;
}
并查集代码
int find(int x){
if(f[x] != x){
int o = f[x];
f[x] = find(f[x]);
d[x] += d[o];
}
return f[x];
}
int main(){
scanf("%d", &n);
for(int i=;i<=n;i++) f[i] = i;
for(int i=;i<=n;i++){
scanf("%d", &x);
int a = find(i), b = find(x);
if(a != b) { f[a] = b; d[i] = d[x]+; }
else min = std::min(min, d[x] + d[i] + );
}
printf("%d\n" ,min);
return ;
}
来写个裸题练练吧!https://www.luogu.org/problemnew/show/P2661
求最小环 —— 并查集 与 Floyd的更多相关文章
- 【bzoj2049】[Sdoi2008]Cave 洞穴勘测——线段树上bfs求可撤销并查集
题面 2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 12030 Solved: 6024 Desc ...
- hdu 1213 求连通分量(并查集模板题)
求连通分量 Sample Input2 //T5 3 //n m1 2// u v2 34 5 5 12 5 Sample Output24 # include <iostream> # ...
- poj 2524 求连通分量(并查集模板题)
求连通分量 Sample Input 10 91 21 31 41 51 61 71 81 91 1010 42 34 54 85 80 0Sample Output Case 1: 1Case 2: ...
- tarjan求lca :并查集+dfs
//参考博客 https://www.cnblogs.com/jsawz/p/6723221.html#include<bits/stdc++.h> using namespace std ...
- HDU3081:Marriage Match II (Floyd/并查集+二分图匹配/最大流(+二分))
Marriage Match II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- TOJ3955: NKU ACM足球赛(并查集+map+细节题)
时间限制(普通/Java):5000MS/15000MS 内存限制:65536KByte 描述 NKU ACM最近要举行足球赛,作为此次赛事的负责人,Lee要对报名人员进行分队.分队要遵循如下 ...
- PAT甲题题解-1021. Deepest Root (25)-dfs+并查集
dfs求最大层数并查集求连通个数 #include <iostream> #include <cstdio> #include <algorithm> #inclu ...
- HDU 3461 Code Lock(并查集的应用+高速幂)
* 65536kb,仅仅能开到1.76*10^7大小的数组. 而题目的N取到了10^7.我開始做的时候没注意,用了按秩合并,uset+rank达到了2*10^7所以MLE,所以貌似不能用按秩合并. 事 ...
- 树上莫比乌斯反演+分层图并查集——cf990G
/* 树上莫比乌斯反演 求树上 满足 d|gcd(au,av) gcd(au,av)的对数f(d) 如何求: 建立200000层新图,即对于每个数建立一个新图 在加边时,给gcd(au,av)的约数层 ...
随机推荐
- egret中场景跳转的动画
原理:创建一个截取当前场景的截图然后对截图进行bitmap处理加上tween.优点:无需任何图片,特效!适用于任何场景! //1.卷帘特效 //2.左右切换移动 //3.直接翻 //4.旋转掉落 // ...
- MySql主从搭建详细步骤
环境: linux64位,一台机器两个实例,主库3306端口,从库3307端口 步骤: 一.下载安装 先下载安装mysql,这里使用了5.7.21版本,具体过程不做详细说明,可自行查资料如何下载 二. ...
- Linux:Gentoo系统的安装笔记(四)
本来以为结束,谁知离正常的系统还是比较远,不过不放弃,这期的笔记我敢肯定是最后一期了,写了那么多我也觉得烦,被gentoo折磨烦了. 安装KDE桌面 选择正确的配置文件 先获取root权限来安装桌面环 ...
- Linux:Linux Mint系统的安装
今天就更新一篇了,其实Linux系统大部分都是用虚拟机来安装的,毕竟Windows系统才是我们常用的系统,而Linux系统只是我们工作时才用的,而且使用虚拟机是非常方便的,不用重启电脑就可以使用另一种 ...
- 18-09-11 软件rpm yum rm卸载 和批量删除
一 在Linux下删除文件用rm命令,具体用法如下: rm [选项] 文件 选项说明: -f -force 忽略不存在的文件,强制删除,无任何提示 -i --interactive 进行交互式地删除 ...
- Openresty 源码安装脚本
Openresty 中文官网地址 http://openresty.org/cn/ #! /bin/bash function openrestyinstall() { cd /opt/openres ...
- C++入门程序作业1
将一个int A[]={ , , ,}定义的可能重复的数字去掉重复的元素. 了解向量,容器如何使用,size,地址的关系,理解unique erase函数的返回值是什么参数 结果:将1,1,1,2 ...
- CSS效果:3D卡片
HTML: <html lang="en"> <head> <meta charset="UTF-8"> <meta ...
- 微信小程序中的小小的遮罩层
<view class='pop_wx_er'> <view>ddddddddddddd</view> <view>ddddddddddddd</ ...
- Representations of graphs
We can choose between two standard ways to represent a graph as a collection of adjacency lists or a ...