最小径集的算法_【ZZ】最小割集Stoer-Wagner算法
一个无向连通网络,去掉一个边集可以使其变成两个连通分量则这个边集就是割集;最小割集当然就权和最小的割集。
可以用最小切割最大流定理:
1.min=MAXINT,确定一个源点
2.枚举汇点
3.计算最大流,并确定当前源汇的最小割集,若比min小更新min
4.转到2直到枚举完毕
5.min即为所求输出min
不难看出复杂度很高:枚举汇点要O(n),最短增广路最大流算法求最大流是O((n^2)m)复杂度,在复杂网络中O(m)=O(n^2),算法总复杂度就是O(n^5);哪怕采用最高标号预进流算法求最大流O((n^2)(m^0.5)),算法总复杂度也要O(n^4)
所以用网络流算法求解最小割集复杂度不会低于O(n^4)。
---------
prim算法不仅仅可以求最小生成树,也可以求“最大生成树”。最小割集Stoer-Wagner算法就是典型的应用实例。
求解最小割集普遍采用Stoer-Wagner算法,不提供此算法证明和代码,只提供算法思路:
1.min=MAXINT,固定一个顶点P
2.从点P用“类似”prim的s算法扩展出“最大生成树”,记录最后扩展的顶点和最后扩展的边
3.计算最后扩展到的顶点的切割值(即与此顶点相连的所有边权和),若比min小更新min
4.合并最后扩展的那条边的两个端点为一个顶点(当然他们的边也要合并,这个好理解吧?)
5.转到2,合并N-1次后结束
6.min即为所求,输出min
prim本身复杂度是O(n^2),合并n-1次,算法复杂度即为O(n^3)
如果在prim中加堆优化,复杂度会降为O((n^2)logn)
这个Stoer-Wagner算法可以参见这篇paper(http://docs.google.com/fileview?id=0BwxLvD9mcDNtMjk3MWVkMTAtZjMzNi00ZWE3LTkxYjQtYTQwNzcyZTk3Njk2&hl=en), 其核心思想是迭代缩小规模, 算法基于这样一个事实:
对于图中任意两点s和t, 它们要么属于最小割的两个不同集中, 要么属于同一个集.
如果是后者, 那么合并s和t后并不影响最小割. 基于这么个思想, 如果每次能求出图中某两点之间的最小割, 然后更新答案后合并它们再继续求最小割, 就得到最终答案了. 算法步骤如下:
1. 设最小割cut=INF, 任选一个点s到集合A中, 定义W(A, p)为A中的所有点到A外一点p的权总和.
2. 对刚才选定的s, 更新W(A,p)(该值递增).
3. 选出A外一点p, 且W(A,p)最大的作为新的s, 若A!=G(V), 则继续2.
4. 把最后进入A的两点记为s和t, 用W(A,t)更新cut.
5. 新建顶点u, 边权w(u, v)=w(s, v)+w(t, v), 删除顶点s和t, 以及与它们相连的边.
6. 若|V|!=1则继续1.
看起来很简单, 每次像做最大生成树一样选最大"边"(注意, 这里其实不是边, 而是已经累计的权值之和, 就当是加权的度好了), 然后把最后进入的两个点缩到一块就可以了. 合并点最多有n-1次, 而不加堆优化的prim是O(n^2)的, 所以最终复杂度O(n^3), 要是你有心情敲一大坨代码, 还可以在稀疏图上用Fibonacci Heap优化一下, 不过网上转了一圈, 大多都是说能用Fibonacci Heap优化到怎样怎样的复杂度, 真正能自己写出来的恐怕也没几个, 看看uoregon(俄勒冈大学)的一大坨代码就有点寒. (http://resnet.uoregon.edu/~gurney_j/jmpc/fib.html)
特别注意几个地方, 网上的好几个Stoer-Wagner版本都存在一些小错误:
1. 算法在做"最大生成树"时更新的不是普通意义上的最大边, 而是与之相连的边的权值和, 当所有边都是单位权值时就是累计度.
2. "最后进入A的两点记为s和t", 网上对s有两种解释, 一是在t之前一个加进去的点, 二是t的前趋节点, 也就是最后选择的那条边的另一端. 正解是第一种!
3. 对于稠密图, 比如这题, 我用堆, 映射二分堆, 或者STL的优先队列都会TLE, 还不如老老实实O(n^3).
另一篇论文:
最小割 Stoer-Wagner 算法
Etrnls 2007-4-15
Stoer-Wagner 算法用来求无向图 G=(V, E)的全局最小割。
算法基于这样一个定理:对于任意s, t V ∈ ,全局最小割或者等于原图的s-t 最小割,或者等于将原图进行 Contract(s,
t)操作所得的图的全局最小割。
算法框架:
1. 设当前找到的最小割MinCut 为+∞
2. 在 G中求出任意 s-t 最小割 c,MinCut = min(MinCut, c)
3. 对 G作 Contract(s, t)操作,得到 G'=(V', E'),若|V'| > 1,则G=G'并转 2,否则MinCut 为原图的全局最
小割
Contract 操作定义:
若不存在边(p, q),则定义边(p, q)权值w(p, q) = 0
Contract(a, b): 删掉点 a, b 及边(a, b),加入新节点 c,对于任意 v V ∈ ,w(v, c) = w(c, v) = w(a, v) + w(b,
v)
求 G=(V, E)中任意 s-t 最小割的算法:
定义w(A, x) = ∑w(v[i], x),v[i] A ∈
定义 Ax 为在x 前加入 A 的所有点的集合(不包括 x)
1. 令集合 A={a},a为 V中任意点
2. 选取 V - A中的 w(A, x)最大的点 x加入集合 A
3. 若|A|=|V|,结束
令倒数第二个加入 A的点为 s,最后一个加入 A的点为 t,则s-t 最小割为 w(At, t)
再加一份模板
/*pku 2914 */
#include
#include
#define NN 504
#define INF 1 << 30
int vis[NN];
int wet[NN];
int combine[NN];
int map[NN][NN];
int S, T, minCut, N;
void Search(){
int i, j, Max, tmp;
memset(vis, 0, sizeof(vis));
memset(wet, 0, sizeof(wet));
S = T = -1;
for (i = 0; i < N; i++){
Max = -INF;
for (j = 0; j < N; j++){
if (!combine[j] && !vis[j] && wet[j] > Max){
tmp = j;
Max = wet[j];
}
}
if (T == tmp) return;
S = T; T = tmp;
minCut = Max;
vis[tmp] = 1;
for (j = 0; j < N; j++){
if (!combine[j] && !vis[j]){
wet[j] += map[tmp][j];
}
}
}
}
int Stoer_Wagner(){
int i, j;
memset(combine, 0, sizeof(combine));
int ans = INF;
for (i = 0; i < N - 1; i++){
Search();
if (minCut < ans) ans = minCut;
if (ans == 0) return 0;
combine[T] = 1;
for (j = 0; j < N; j++){
if (!combine[j]){
map[S][j] += map[T][j];
map[j][S] += map[j][T];
}
}
}
return ans;
}
int main()
{
int a, b, c, M;
while(scanf("%d%d", &N, &M) != EOF){
memset(map, 0, sizeof(map));
while(M--){
scanf("%d%d%d", &a, &b, &c);
map[a][b] += c;
map[b][a] += c;
}
printf("%d\n", Stoer_Wagner());
}
return 0;
}
最小径集的算法_【ZZ】最小割集Stoer-Wagner算法相关推荐
- Python_机器学习_算法_第1章_K-近邻算法
Python_机器学习_算法_第1章_K-近邻算法 文章目录 Python_机器学习_算法_第1章_K-近邻算法 K-近邻算法 学习目标 1.1 K-近邻算法简介 学习目标 1 什么是K-近邻算法 1 ...
- 错误录入 算法_如何使用验证错误率确定算法输出之间的关系
错误录入 算法 Monument (www.monument.ai) enables you to quickly apply algorithms to data in a no-code inte ...
- 利用python语言实现分类算法_使用python实现kNN分类算法
k-近邻算法是基本的机器学习算法,算法的原理非常简单: 输入样本数据后,计算输入样本和参考样本之间的距离,找出离输入样本距离最近的k个样本,找出这k个样本中出现频率最高的类标签作为输入样本的类标签,很 ...
- prim算法_最小生成树(Kruskal和Prim算法)
文章和资源同步更新至微信公众号:算法工程师之路 8月份会开启每日算法题系列,值得期待哦 上一篇文章,我们讲了图的创建和遍历,其中遍历的算法主要有BFS(广度优先算法)和DFS(深度优先算法)两种,并且 ...
- java实现apriori算法_七大经典、常用排序算法的原理、Java 实现以及算法分析
0. 前言 大家好,我是多选参数的程序员,一个正再 neng 操作系统.学数据结构和算法以及 Java 的硬核菜鸡.数据结构和算法是我准备新开的坑,主要是因为自己再这块确实很弱,需要大补(残废了一般) ...
- 沃舍尔算法_[数据结构拾遗]图的最短路径算法
前言 本专题旨在快速了解常见的数据结构和算法. 在需要使用到相应算法时,能够帮助你回忆出常用的实现方案并且知晓其优缺点和适用环境.并不涉及十分具体的实现细节描述. 图的最短路径算法 最短路径问题是图论 ...
- 路径规划算法_自动驾驶汽车路径规划算法浅析
自动驾驶汽车的路径规划算法最早源于机器人的路径规划研究,但是就工况而言却比机器人的路径规划复杂得多,自动驾驶车辆需要考虑车速.道路的附着情况.车辆最小转弯半径.外界天气环境等因素. 本文将为大家介绍四 ...
- weka java 分类算法_使用Weka快速实践机器学习算法
[译者注]在当下人工智能火爆发展的局面,每时每刻都有新的技术在诞生,但如果你是一个新手,Weka或许能帮助你直观.快速的感受机器学习带来的解决问题的新思路. Weka使机器学习的应用变得简单.高效并且 ...
- smoteenn算法_基于EasyEnsemble算法和SMOTE算法的不均衡数据分类方法与流程
本发明涉及不均衡数据二分类技术领域,尤其涉及一种基于EasyEnsemble算法和SMOTE算法的不均衡数据二分类方法. 背景技术: 数据不均衡指的是在一个样本数据集中,某一类的样本数远少于其他类的样 ...
- matlab 腐蚀算法,【zz】matlab 腐蚀膨胀算法
1.图像膨胀的Matlab实现: 可以使用imdilate函数进行图像膨胀,imdilate函数需要两个基本输入参数,即待处理的输入图像和结构元素对象.结构元素对象可以是strel函数返回的对象,也可 ...
最新文章
- 如何提升微服务的幸福感
- 一个程序员眼中的好UI
- 计算机职称excel2007,职称计算机Excel2007中文电子表格考试大纲
- Maximum.TV 发布西班牙语Silverlight TV网站
- 详解CSS的相对定位和绝对定位
- beaninfo详解源码解析 java_Java后端精选技术:源码解析Spring Cloud Zuul
- C编译: 使用gdb调试
- 迭代器 in C++
- python不显示warnings
- HighNewTech:一文了解计算机思维、数学思维的本质区别,以及算法和程序的认知比较
- 【舆情聚焦】 乐视危机舆情监测专项报告
- gnu coreutils4.5.1 hostid.c源码解读
- PS利用切片工具将一张大图裁剪成多个子图像并导出
- Java SSM 项目实战 day08 方法级别的权限操作 服务器端的权限控制(JSR-250注解)(支持表达式的注解)(@Secured)以及页面端的权限控制
- [h5棋牌项目]-05-重载配置导致的内存泄露
- 设置文字为计算机屏幕保护,win10系统设置炫酷三维文字屏幕保护的具体技巧
- mac_命令行删除Git本地库
- 初识 Linux — 文本编辑器
- 并发模拟的四种方式+工具,超级实用!
- 20155305乔磊2016-2017-2《Java程序设计》第六周学习总结
热门文章
- 什么软件测试情侣头像,情侣头像另一半怎么找,请问什么软件可以找出
- [web开发] Vue+Spring Boot 上海大学预约系统开发记录
- java源码之 io 流源码解读(一)
- 加入域的计算机如何本地用户登录,关于本地缓存登陆和域用户将计算机加入域的问题(转)...
- 苹果开发者证书报错证书不受信任
- Aspose.Cells 使用FreezePanes()冻结行和列
- 在excel 同时冻结行和列
- 计算机表格快捷键,EXCEL表格所有的快捷键《excel一键到底 快捷键》
- Teams会议聊天中无法添加其他人解决方案
- 解决网页文字不能复制,复制网页文字的方法