求最小环 —— 并查集 与 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)的约数层 ...
随机推荐
- 关于Flex布局
Flex是Flexible Box的缩写,意为“弹性布局”.弹性布局提供了一种更加有效的方式来对一个容器内的项目进行排列/对齐/分配空间等操作,让盒模型具有更大的灵活性.在一个容器盒子上添加displ ...
- 解决tomcat内存溢出,java.lang.OutOfMemoryError: PermGen space
一.通过eclipse启动tomcat. 1.选择window>>preferences 2.搜索tomcat,找到自己安装的tomcat版本对应的JDK,在Optional Java V ...
- impala和kudu使用的小细节
七堇年:我们要有最朴素的生活与最遥远的梦想 . 即使明日天寒地冻,路远马亡. 加油! 之前入门的小错误总结,建表都会出错,真的好尴尬 还是要做好笔记 第一个错误: error:AnalysisEx ...
- PAT A1059
PAT A1059 标签(空格分隔): PAT 解题思路 :先打印出素数表.利用结构体数组来存贮质因子的值和个数 strcut factor{ int x; //值 int cnt; //个数 }fa ...
- 1011. World Cup Betting (20)
生词(在文中的意思) tie 平局 lay a bet 打赌 putting their money where their mouths were 把他们的钱用在刀刃上 manner of 的方式 ...
- JVM概念以及常用设置
DAY 1 Jvm- java虚拟机 类加载子系统 加载class文件到方法区 方法区 存放类信息 常量信息 常量池信息 辅助堆栈的永久区,解决堆栈信息的产生,是先决条件 3. Java堆(重要) ...
- c++学习过程
作者本人也是一名初学者,我的QQ:2522929921,可以一起交流啊! 希望广大初学者能够一起进步: 1.掌握编程思维真的很重要!!!!***. 2.不能刻意记忆语法规则. 3.在循序渐进的项目实战 ...
- centos6 升级安装openssh7
1.准备工作: 查看下当前SSH版本: [root@bogon ~]# ssh -V OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013 或者 [root@b ...
- CentOS系统Nginx安装配置,随时更新
./configure --prefix=/etc/nginx \ #指定安装目录 --sbin-path=/usr/sbin/nginx \ #指定执行路径--conf-path=/etc/ngin ...
- Android作业
一.设置跑马灯功能 使用滚动字幕显示标题“请选择你喜欢哪种花” <?xml version="1.0" encoding="utf-8"?>&l ...