poj2914-Minimum Cut
题意
\(n\) 个点 \(m\) 条边的无向带权图求全局最小割。\(n\le 500,m\le \frac{n(n-1)}{2}\) 。
分析
参考了 这篇博客,去给他点赞。
嘛,今天研究了一下全局最小割。
全局最小割是什么呀?
运用经典的最大流最小割,我们可以在网络流复杂度内求出对于两个点 \(s,t\) ,把图分成 \(s\in S\) 集和 \(t\in T\) 集的需要去掉的最小边权和。我们称这种割为对于一组点 \((s,t)\) 的 \(s-t\) 割。
全局最小割,就是把整个无向图割开,却不指定怎么割,求最小边权和。
用之前的方法,\(O(n*网络流)\) 可以分治得到最小割树,从而求出任意两点间的最小割,那么取最小边权就是答案。但已知理论复杂度比较优秀的网络流算法复杂度也达到 \(O(n^2\sqrt m)\) (最高标号预留推进),再乘上 \(n\) ,这是一个很高的复杂度。
是否有办法优化呢?这个问题中 不指定要割什么 这个条件并没有用上,可以从这里入手。
下面就来介绍全局最小割的 Stoer-Wagner 算法。
整体思路
解决这个问题,有一个关键的性质需要利用。
设 \(s,t\) 为图中两点,那么在任意一个割中,它们要么在同一个集合中,要么在不同的集合中。
算法的整体思路是,我们不指定割开哪两个点,而是设计一个函数 \(f(G)\) ,返回一个三元组 \((s,t,c)\) ,表示这个图中 \((s,t)\) 的最小割为 \(c\) 。注意,这个函数告诉我们它割开哪两个点,而不是我们告诉它 。利用上面的性质,要么这个图的全局最小割要么就是 \(c\) ,要么 \(s,t\) 在同一集合中。
为什么是这样呢?显然图的全局最小割一定小于等于 \(c\) ,若全局最小割下 \(s,t\) 在不同集合中,而全局最小割却小于 \(c\) ,那么必然存在更小的 \(s-t\) 割,这与 \(c\) 是 \(s-t\) 最小割矛盾。
我们把答案对 \(c\) 取 \(\min\),接下来就讨论 \(s,t\) 在同一集合中的情况。若是这样,那么其实可以把 \(s,t\) 并起来,因为 \(s\) 与 \(t\) 中间的边是不会割掉的。所以就把 \(s,t\) 并起来,把边合并就好啦!
这样进行,直到图中只剩下一个点,我们就得到了答案。显然上面的过程进行了 \(n-1\) 次,所以复杂度为 \(O(n(m+f))\) 。接下来只要我们能够有一个函数,快速地告诉我们一对点间的最小割,问题就解决啦。
函数 \(f(G)\)
算法流程
- 有一个空集 \(A\) ,最开始在 \(G\) 中任意找一个点放进 \(A\) 。
- 不断在 \(G\) 中找到一个点 \(v\notin A\) 使得它到 \(A\) 中所有连边权值和最大,把这个点加入 \(A\) ,直到 \(A=V\) 。
- 倒数第二个加入 \(A\) 和最后加入 \(A\) 的两点即分别为 \(s,t\) ,它们的最小割是 \(t\) 到 \(V-\lbrace t \rbrace\) 的边权和。
下面证明这个算法的正确性。实际上要说明的是,对于任意一个点集的划分 \(V=S+T\) 使得 \(s\in S,t\in T\) ,有 \(cut(V-\lbrace t\rbrace,\lbrace t\rbrace)\le cut(S,T)\) 。
一些记号
- \(w(e)\) ,边 \(e\) 的权值;\(w(x,y)\) ,边 \((x,y)\) 的权值
- \(w(S,x)=\sum _{v\in S,(x,v)\in E}w(x,v)\)
- \(C\) ,对于点集的划分 \(S,T\) 的最小割
- \(a\) ,加入 \(A\) 的点的序列,\(a_i\) 表示第 \(i\) 个加入 \(A\) 的点
- \(A_x\) ,加入 \(x\) 之前加入 \(A\) 的点的集合,不包含 \(x\)
- \(C_x\) ,\(\lbrace (u,v)|u,v\in A_x\cap\lbrace x\rbrace,(u,v)\in C\rbrace\) 。此处 \(C\) 就是上面的那个,即 \(C\) 在 \(A_x\cap \lbrace x\rbrace\) 中的诱导割。
- \(B\setminus C\) ,\(B\) 集合中去掉集合 \(C\) 剩下的集合,即 \(C\) 在 \(B\) 中的补集。
接下来要证明,对于所有点 \(v\) 满足 \(a\) 中排 \(v\) 前面的点与 \(v\) 不在割 \(C\) 的同一侧,有 \(w(A_v,v)\le C_v\) 。若能得到这个,由于 \(t\) 是满足这个条件的,就有 \(w(A_t,t)=w(V-\lbrace t\rbrace,t)=cut(V-\lbrace t\rbrace,\lbrace t\rbrace)\le C_t\) ,即得到上面的结论。
对第一个满足条件的 \(v\) ,等号成立,因为 \(v\) 是第一个不与前面在同一集合中的点,所以 \(C_v\) 就是 \(w(A_v,v)\) ,这些边是一定要割掉的。下面对 \(v\) 用归纳法。
设对于一个满足条件的 \(v\) 以及前面满足条件的点,结论都成立,那么对于 \(v\) 的下一个点 \(u\) ,说明这个结论成立。
首先有 \(w(A_u,u)=w(A_v,u)+w(A_u\setminus A_v,u)\) ,这是显然的,因为它是对集合 \(A_u\) 的一个划分。
由归纳假设可得,\(w(A_v,v)\le C_v\) ,又因为算法过程告诉我们 \(u\) 在 \(v\) 后面加入,所以在加入 \(v\) 之前一刻,\(v\) 与 \(A_v\) 的连边权值和大于 \(u\) 与 \(A_v\) 连边的权值和,所以有 \(w(A_v,u)\le w(A_v,v)\) ,于是得到:
w(A_v,u)\le w(A_v,v)\le C_v && (1)
\end{aligned}
\]
\(C_u\) 的含义,是在一个 \((S,T)\) 割中要把 \(A_u\cap \lbrace u\rbrace\) 割成两部分的那部分。这一定包含了 \(C_v\) ,因为 \(v\) 与之前的那个也不再同一个集合中。\(w(A_u\setminus A_v,u)\) 一定是要割掉的,否则就无法保证 \(u\) 与之前的那个不在同一集合中。于是得到:
C_v+w(A_u\setminus A_v,u)\le C_u && (2)
\end{aligned}
\]
联立上两式,得到:
\]
这样我们证明了结论。
函数 \(f\) 的复杂度直接做是 \(O(m+n^2)\) ,可以用斐波那契堆优化到 \(O(m+n\log n)\) (普通堆是 \(O((m+n)\log n)\) ,在稠密图中与 \(O(m+n^2)\) 没有什么区别)。因此整个算法的复杂度为 \(O(nm+n^3)\) 或 \(O(nm+n^2\log n)\) 。
代码
#include<cstdio>
#include<cctype>
#include<climits>
#include<cstring>
#include<algorithm>
#define M(x) memset(x,0,sizeof x)
using namespace std;
inline int read() {
int x=0,f=1;
char c=getchar();
for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
for (;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
const int maxn=1e3+1;
int n,m;
namespace graph {
int d[maxn],f[maxn][maxn],ed;
bool no[maxn],ina[maxn];
inline void clear() {M(no),M(f);}
inline void add(int x,int y,int w) {
f[x][y]+=w;
}
void newlink(int nw,int s,int t) {
for (int v=1;v<=ed;++v) if (!no[v] && v!=t) {
add(nw,v,f[s][v]);
add(v,nw,f[s][v]);
}
}
inline void push(int x) {
ina[x]=true;
for (int v=1;v<=ed;++v) if (!no[v] && !ina[v]) d[v]+=f[x][v];
}
int glob(int cs,int &s,int &t) {
M(d),M(ina);
int a;
for (a=1;a<=ed && (no[a] || ina[a]);++a);
push(t=a);
while (cs--) {
int p=0;
for (int i=1;i<=ed;++i) if (!no[i] && !ina[i] && d[i]>d[p]) p=i;
s=t,t=p;
push(p);
}
return d[t];
}
int run() {
int ret=INT_MAX,here=(n-1)<<1;
for (ed=n;ed<=here;++ed) {
int s=0,t=0,g=glob((n<<1)-ed-1,s,t);
ret=min(ret,g);
int nw=ed+1;
newlink(nw,s,t);
newlink(nw,t,s);
no[s]=no[t]=true;
}
return ret;
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
#endif
while (~scanf("%d%d",&n,&m)) {
graph::clear();
for (int i=1;i<=m;++i) {
int x=read()+1,y=read()+1,w=read();
graph::add(x,y,w),graph::add(y,x,w);
}
int ans=graph::run();
printf("%d\n",ans);
}
return 0;
}
poj2914-Minimum Cut的更多相关文章
- poj2914 Minimum Cut 全局最小割模板题
Minimum Cut Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 8324 Accepted: 3488 Case ...
- POJ2914 Minimum Cut —— 最小割
题目链接:http://poj.org/problem?id=2914 Minimum Cut Time Limit: 10000MS Memory Limit: 65536K Total Sub ...
- POJ Minimum Cut
Minimum Cut Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 9302 Accepted: 3902 Case ...
- POJ 2914 Minimum Cut
Minimum Cut Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 9319 Accepted: 3910 Case ...
- hdu 5452 Minimum Cut 树形dp
Minimum Cut Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=54 ...
- POJ 2914 Minimum Cut 最小割图论
Description Given an undirected graph, in which two vertices can be connected by multiple edges, wha ...
- HDU 6214.Smallest Minimum Cut 最少边数最小割
Smallest Minimum Cut Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Oth ...
- HDU 6214 Smallest Minimum Cut(最少边最小割)
Problem Description Consider a network G=(V,E) with source s and sink t. An s-t cut is a partition o ...
- Smallest Minimum Cut HDU - 6214(最小割集)
Smallest Minimum Cut Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Oth ...
- HDU - 6214:Smallest Minimum Cut(最小割边最小割)
Consider a network G=(V,E) G=(V,E) with source s s and sink t t . An s-t cut is a partition of nodes ...
随机推荐
- 20155334 实验五 Java网络编程及安全
20155334 实验五 Java网络编程及安全 实验内容 1.掌握Socket程序的编写: 2.掌握密码技术的使用: 3.设计安全传输系统. 实验步骤 实验1: 参考 结对实现中缀表达式转后缀表达式 ...
- 20155339 2016-2017-2 《Java程序设计》第1周学习总结
20155339 2016-2017-2 <Java程序设计>第1周学习总结 教材学习内容总结 第一章 一直以为JAVA应该只是一种语言,研读了书本之后发现原来JAVA也代表了解决问题的平 ...
- 系统分析与设计——WordCount
成果: https://gitee.com/ZMLJZ/codes/0k19q4upgmrfde265l7vx36 作业要求: 根据WordCount的需求描述,先编程实现,再编写单元测试,最后撰写博 ...
- [BZOJ1565][NOI2009]植物大战僵尸-[网络流-最小割+最大点权闭合子图+拓扑排序]
Description 传送门 Solution em本题知识点是用网络流求最大点权闭合子图. 闭合图定义:图中任何一个点u,若有边u->v,则v必定也在图中. 建图:运用最小割思想,将S向点权 ...
- day 4 名片管理系统 -函数版
修改没有用函数的程序 具有独立功能的代码块 源程序 #1.打印功能信息 print("*"*50) print("\t名片管理系统 V3\t") print(& ...
- JS的发布订阅模式
JS的发布订阅模式 这里要说明一下什么是发布-订阅模式 发布-订阅模式里面包含了三个模块,发布者,订阅者和处理中心.这里处理中心相当于报刊办事大厅.发布者相当与某个杂志负责人,他来中心这注册一个的杂志 ...
- 数据结构思维导图 Part1
刚刚结束数据结构的学习,在复习阶段,所以做来思维导图总结一下. 思维导图,顾名思义是应该有对思维有引导作用的,就像思维的整理术,然而想要学好什么,光看思维导图总是不够的. 树与图作为两个复杂非线性结构 ...
- svn 配置仓库
1.新建一个空文件夹,然后点击--在此创建版本库. 2.修改conf 下的 svnserve.conf : anon-access = read auth-access = write passwor ...
- Scrapy爬豆瓣电影Top250并存入MySQL数据库
d:进入D盘 scrapy startproject douban创建豆瓣项目 cd douban进入项目 scrapy genspider douban_spider movie.douban.co ...
- 2.5星|《哈佛商学院管理与MBA案例全书》:书名太唬人了,依据中文经管书汇编整理而成
哈佛商学院管理与MBA案例全书(套装十册) 看到最后,列出的参考书目中全部是中文经管书,才明白这本书不是哈佛商学院出版的,是国内的编辑做的汇编.参考书目中除了中文经管书之外,还有一套<哈佛商学院 ...