#1378 : 网络流二·最大流最小割定理

题目链接:http://hihocoder.com/problemset/problem/1378?sid=1393576

时间限制:10000ms

单点时限:1000ms

内存限制:256MB

描述

小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么?

小Ho:我记得!网络流就是给定了一张图G=(V,E),以及源点s和汇点t。每一条边e(u,v)具有容量c(u,v)。网络流的最大流问题求解的就是从s到t最多能有多少流量。

小Hi:那这个问题解决办法呢?

小Ho:解决网络流的基本思路就是寻找增广路,不断更新残留网络。直到找不到新的增广路,此时得到的流就是该网络的最大流。

小Hi:没错,看来你记得很牢嘛。

小Ho:哎嘿嘿,不过这里我有一个问题,为什么找不到增广路时就已经找到了最大流呢?

小Hi:这一次我就来解决你的疑惑,首先我们要从网络流的割开始讲起。

对于一个网络流图G=(V,E),其割的定义为一种点的划分方式:将所有的点划分为S和T=V-S两个部分,其中源点s∈S,汇点t∈T。

对于一个割(S,T),我们定义净流f(S,T)表示穿过割(S,T)的流量之和,即:

f(S,T) = Σf(u,v) | u∈S,v∈T

举个例子(该例子选自算法导论):

净流f = f(2,4)+f(3,4)+f(3,5) = 12+(-4)+11 = 19

同时我们定义割的容量C(S,T)为所有从S到T的边容量之和,即:

C(S,T) = Σc(u,v) | u∈S,v∈T

同样在上面的例子中,其割的容量为:

c(2,4)+c(3,5)=12+14=26

小Ho:也就是说在计算割(S,T)的净流f(S,T)时可能存在反向的流使得f(u,v)<0,而容量C(S,T)一定是非负数。

小Hi:你这么说也没错。实际上对于任意一个割的净流f(S,T)总是和网络流的流量f相等。比如上面例子中我们改变一下割的方式:

可以计算出对于这两种情况净流f(S,T)仍然等于19。

一个直观的解释是:根据网络流的定义,只有源点s会产生流量,汇点t会接收流量。因此任意非s和t的点u,其净流量一定为0,也即是Σ(f(u,v))=0。而源点s的流量最终都会通过割(S,T)的边到达汇点t,所以网络流的流f等于割的静流f(S,T)。

严格的证明如下:

f(S,T) = f(S,V) - f(S,S)
从S到T的流等于从S到所有节点的流减去从S到S内部节点的流
f(S,T) = f(S,V)
由于S内部的节点之间存在的流一定有对应的反向流,因此f(S,S)=0
f(S,T) = f(s,V) + f(S-s,V)
再将S集合分成源点s和其他属于S的节点
f(S,T) = f(s,V)
由于除了源点s以外其他节点不会产生流,因此f(S-s,V)=0
f(S,T) = f(s,V) = f

所以f(S,T)等于从源点s出来的流,也就是网络的流f。

小Ho:简单理解的话,也就是说任意一个割的净流f(S,T)都等于当前网络的流量f

小Hi:是这样的。而对于任意一个割的净流f(S,T)一定是小于等于割的容量C(S,T)。那也即是,对于网络的任意一个流f一定是小于等于任意一个割的容量C(S,T)。

而在所有可能的割中,存在一个容量最小的割,我们称其为最小割

这个最小割限制了一个网络的流f上界,所以有:

对于任一个网络流图来说,其最大流一定是小于等于最小割的。

小Ho:但是这和增广路又有什么关系呢?

小Hi:接下来就是重点了。利用上面讲的知识,我们可以推出一个最大流最小割定理

对于一个网络流图G=(V,E),其中有源点s和汇点t,那么下面三个条件是等价的:
1. 流f是图G的最大流
2. 残留网络Gf不存在增广路
3. 对于G的某一个割(S,T),此时f = C(S,T)

首先证明1 => 2

我们利用反证法,假设流f是图G的最大流,但是残留网络中还存在有增广路p,其流量为fp。则我们有流f'=f+fp>f。这与f是最大流产生矛盾。

接着证明2 => 3

假设残留网络Gf不存在增广路,所以在残留网络Gf中不存在路径从s到达t。我们定义S集合为:当前残留网络中s能够到达的点。同时定义T=V-S。
此时(S,T)构成一个割(S,T)。且对于任意的u∈S,v∈T,有f(u,v)=c(u,v)。若f(u,v)<c(u,v),则有Gf(u,v)>0,s可以到达v,与v属于T矛盾。
因此有f(S,T)=Σf(u,v)=Σc(u,v)=C(S,T)。

最后证明3 => 1

由于f的上界为最小割,当f到达割的容量时,显然就已经到达最大值,因此f为最大流。

这样就说明了为什么找不到增广路时,所求得的一定是最大流。

小Ho:原来是这样,我明白了。

输入

第1行:2个正整数N,M。2≤N≤500,1≤M≤20,000。

第2..M+1行:每行3个整数u,v,c(u,v),表示一条边(u,v)及其容量c(u,v)。1≤u,v≤N,0≤c(u,v)≤100。

给定的图中默认源点为1,汇点为N。可能有重复的边。

输出

第1行:2个整数A B,A表示最小割的容量,B表示给定图G最小割S集合的点数。

第2行:B个空格隔开的整数,表示S集合的点编号。

若存在多个最小割可以输出任意一个的解。

样例输入

6 7
1 2 3
1 3 5
2 4 1
3 4 2
3 5 3
4 6 4
5 6 2

样例输出

5 4
1 2 3 5

解题思路:这个题主要是巩固一下网络流的一下定理概念以及如何求割集。

我们从源点出发,如过f(u,v)没有流满则说明s点能够到达v点,v属于s

找到所有的属于s的点剩下的就是属于t的点。

大概证明:就是属于最小割的边u都属于集合s,v都属于集合u,u->v之间的边都是流满的

所以这些流量被减去后就将一个图分成了两个集合,源点s能够到达的点就是属于s集合的点。

因为题目说明最多有20000条边,刚开始的时候边数开的太小了一直tle。。。

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<set>
#include<algorithm>
#include<cstring>
using namespace std;
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define sca(x) scanf("%d",&x)
#define per(i,j,k) for(int i=j;i>=k;i--)
#define inf 0x3f3f3f3f
#define LL long long
#define N 40005
#define inf 0x3f3f3f3f
const LL mod = 998244353;struct edg
{int to,w,nt;
}g[N];struct node
{int v,id;
}pre[505];int tot;
int head[505],vis[505];
void addedg(int u,int v,int w)
{g[tot].to=v;g[tot].w=w;g[tot].nt=head[u];head[u]=tot++;
}bool bfs(int s,int t)
{memset(vis,false,sizeof(vis));queue<int>q;q.push(s);vis[s]=true;while(!q.empty()){int u=q.front();q.pop();for(int i=head[u];i!=-1;i=g[i].nt){int to=g[i].to;if(!vis[to]&&g[i].w>0){//cout<<"u->to "<<u<<" "<<to<<endl;vis[to]=true;pre[to].v=u;pre[to].id=i;if(to==t)return true;q.push(to);}}}return false;}void get_set(int s,int t)
{set<int>ss;memset(vis,false,sizeof(vis));queue<int>q;q.push(s);vis[s]=true;while(!q.empty()){int u=q.front();q.pop();ss.insert(u);for(int i=head[u];i!=-1;i=g[i].nt){int to=g[i].to;if(!vis[to]&&g[i].w>0){vis[to]=true;q.push(to);}}}printf("%d\n",ss.size());set<int>::iterator it;for(it=ss.begin();it!=ss.end();it++){printf("%d",*it);if(it!=ss.end())printf(" ");}printf("\n");
}
void EK(int s,int t)
{int ans=0;while(bfs(s,t)){int mini=inf;for(int i=t;i!=s;i=pre[i].v){mini=min(mini,g[pre[i].id].w);}for(int i=t;i!=s;i=pre[i].v){g[pre[i].id].w-=mini;g[pre[i].id^1].w+=mini;}ans+=mini;}//cout<<"ans="<<ans<<endl;printf("%d ",ans);get_set(s,t);
}void init()
{memset(head,-1,sizeof(head));memset(pre,-1,sizeof(pre));tot=0;
}int main()
{int n,m;scanf("%d%d",&n,&m);init();rep(i,1,m){int u,v,w;scanf("%d%d%d",&u,&v,&w);addedg(u,v,w);addedg(v,u,0);}EK(1,n);
}

最大流最小割定理 (定理,割集)相关推荐

  1. 最大流最小割定理(max flow/min cut theory)

    百度文库里面有个地址,讲的比较详细. http://wenku.baidu.com/link?url=gPXhYCduLNgZaOkKIltNDAgPGwuMTpRX7a0utvVFuqDAP9o1j ...

  2. 流网络的最小割问题c语言,网络流基础-最大流最小割定理

    最大流最小割定理,指网络流的最大流等于其最小割. 最大流指符合三个性质的前提下,从S到T能流过的最大流量. 最小割指符合割的定义,最小的割容量. 求最大流: 不断寻找增广路,计算能增加的最小流量,然后 ...

  3. hihocoder 网络流二·最大流最小割定理

    网络流二·最大流最小割定理 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? ...

  4. nyoj 677 碟战(最大流最小割定理)

    碟战 时间限制:2000 ms  |  内存限制:65535 KB 难度:4 描述 知己知彼,百战不殆!在战争中如果被敌人掌握了自己的机密,失败是必然的.K国在一场战争中屡屡失败,就想到自己的某些城市 ...

  5. GraphCut、最大流最小割定理

    G=(V,E):V为点集,E为边集: 节点集V中的节点分为: (1)终端节点.不包含图像像素,用S和T表示.S为源点,T为汇点.图像分割中通常用S表示前景目标,标签设为1:T表示背景,标签为0. (2 ...

  6. Cable TV Network POJ - 1966 最大流最小割定理 点边转化

    最大流最小割定理 任何一个网络的最大流量等于最小割中边的容量之和 即最大流等于最小割 点边转化 节点可以拆为入点和出点 把点的属性添加到入点和出点之间的边上 图的边也可以分两截 在中间加一个节点 把边 ...

  7. UVA-10480 Sabotage(最大流最小割定理+输出路径)

    题目链接:UVA-10480 Sabotage The regime of a small but wealthy dictatorship has been abruptly overthrown ...

  8. 网络流(二)——最大流最小割定理

    最小割 <1>什么是割?     引例:你的仇人是一个工厂老板.你要炸掉一些车,让他每个货物都运不到销售点.         炸掉越大的车,你越容易被发现.你希望炸掉的车的容量之和尽量小. ...

  9. 网络流 最大流最小割与最小费用流

    目录 [镇楼] [引入] [基本定义和概念] [最大流算法] [最小割] [最小费用最大流] [引用] [镇楼]   天啦真的好好懂!!!麻麻再也不用担心我的网络流学习啦!!! [引入] 首先,我们来 ...

  10. Algo_网络流,最大流最小割总结, 残留网络性质,知识点总结Tips

    catalog 最大流算法 错误点 错误点 残留网络的 可叠加性 流网络的 点和边 最小割定理证明 version_0 version_1 最大流算法 错误点 for( int i = 0; i &l ...

最新文章

  1. 在VC下执行DOS命令(VC执行EXE)
  2. 让C/C++程序员告诉你什么叫浪漫,表白黑科技
  3. linux 上安装ntop
  4. android-ndk-aide,NDK安装教程20180605
  5. python 通过索引迭代列表_python – NumPy – 迭代2D列表和打印(行,列)索引
  6. 图像加密之灰度加密:基于 密钥 × 解钥 ≡ 1 mod 灰度级 的一轮加密算法例子——lena图
  7. 【智能路由器】轻量级web服务器lighttpd架设——打造家庭影院
  8. easydarwin 安装_easydarwin支持什么格式
  9. 14、Date and Time (日期和时间)
  10. 蓝光护目镜 v6.66.6.3
  11. wps纸张大小设置成A4_pdf两页合并一页a4,只需这招轻松搞定
  12. 激光粒度仪测试原理及详情解答【注解】
  13. 卡西欧科学计算机使用方法,卡西欧计算器使用说明
  14. Failed to decode response: zlib_decode(): data error Retrying with degraded mode, check
  15. 柏西机器人_《勿忘我》孔木猴 ^第9章^ 最新更新:2020-07-25 08:35:09 晋江文学城_手机版...
  16. Unity Gamma Linear Color Space
  17. 极米 Z7X参数 极米 Z7X评测
  18. 简述windows计算机启动过程,计算机启动过程
  19. Java并发编程笔记(1)基础知识
  20. 你的福利是咋被百度云盘给和谐的

热门文章

  1. solidworks新建工程图默认单位为毫米
  2. oracle财务官方文档,oracle财务软件简明操作.docx
  3. JAVA之所得税计算器
  4. github清华大学计算机系课程攻略,GitHub 项目推荐|清华大学计算机系课程相关资源集合|内容丰富...
  5. android半透明引导页
  6. 用于温度测量的热敏电阻
  7. 【信息技术】【2014】【含源码】PGP加密软件
  8. CrossApp 1.1.6新鲜出炉
  9. 飞Young任意路由器连接[破解路由器限制]
  10. 全面开创城市数字经济新时代