您的位置:首页 > 其它

8.21上课感悟

2017-08-21 20:40 176 查看
下午讲网络流……

尽管第一次学,但感觉还是比较不错的,学到很多东西

概念

我们定义 G=(V,E,C)为一个有向图. C 表示边的最大流量

必须时刻保证没有一条边的流量大于它的最大流量,也不能为负

定义源点 S和汇点 T,表示流量都从源点入,都从汇点出

除了源点和汇点之外,其他点不能储存流(就是流进多少,就流出多少)

可行流:

我们定义 flowu,v表示从 u到 v的边中的流量

那么可行流必须满足两个条件:

1. 0≤flowu,v≤Cu,v

2.∑flowu,v=∑flowv,u(即流进多少,流出多少)

这时 flow就是 G的可行流

网络流的对称性: flowu,v=−flowv,u

网络的流:

我们定义 ω=∑flowS,i−∑flowi,s=∑flowi,T−∑flowT,i

当ω最大的时候,说明ω为最大流

增广路:从源点到汇点的一条可行路

注:有一个比较显然的性质:流可以拆分成多个比较小的流

最大流

上面的概念比较多,打得比较累……

终于要说说最大流这个重要的东西了

感兴趣的同学可以先看看Ford-Fulkerson方法

这个方法能证明最大流-最小割定理

同时也可以十分正确地求解最大流

先讲讲最简单的但效率很低的EK算法(是用bfs对Ford-Fulkerson方法的优化)

从源点出发,用一遍bfs求出一条增广路的流

将最大流的答案加上这个流的大小

如果流为0,说明找不到增广路了,最大流求解完毕

流不为0的时候,对流进行调整

在调整的过程中需要建立反向边

反向边的作用:可以帮助你反悔,即在下一次做的时候可以更加方便的找到一条路径,而不会存在本来有路径而就是找不到的尴尬

可能这一顿理论讲得比较虚,看一下代码会比较好

int EK(){//认定1是源点,n是汇点
int maxflow=0;//表示最大流
queue<int> q;
memset(flow,0,sizeof(flow));
memset(pre,0,sizeof(pre));//pre表示i点是从哪里来的
while(1){//用bfs来寻找增广路,然后求解最大流
memset(mn,0,sizeof(mn));//mn数组可以知道是否到了每一个点和当前这个点的瓶颈是什么
mn[1]=INT_MAX;q.push(1);
while(!q.empty()){//bfs过程
int x=q.front();q.pop();
for(int i=1;i<=n;i++)
if(!mn[i]&&flow[x][i]<C[x][i]){
mn[i]=min(mn[x],C[x][i]-flow[x][i]);
pre[i]=x;q.push(i);
}
}
if(!mn
) break;//如果找不到增广路,说明求解完毕
maxflow+=mn
;
for(int tmp=n;tmp!=1;tmp=pre[tmp])
flow[pre[tmp]][tmp]+=mn
,flow[tmp][pre[tmp]]-=mn
;//调整网络,修改边和反向边的流量
}
return maxflow;
}


反向边的过程可能比较难以理解,可以看看网上其他人的讲解

dinic算法后续再讲,是对EK算法的改进

最后再提一个东西,就是最大流-最小割定理

往往要求最小割的时候直接可以求最大流

相关习题

1.狼抓兔子(题目戳这里

求最大流的一个问题

但是直接用dinic求最大流会T(接近O(N^3))

所以我们会想到最大流-最小割定理

最大流和最小割似乎可以相互转化?



将空白三角形的地方作为点,如图连边,求点S到点T的最短路即可

为什么?因为S-T的路径一定是一个切割

所以我们只要求出最小割就可以了

尽管用最小割来求最大流的比较少,主要是用最大流求最小割

2.方格取数问题

在一个 N∗M的一个棋盘中,每一个方格里都有一个正整数权值

现在要在方格里取数,必须要满足取数的方格中两两没有公共边,并且要使得最后取出的权值总和最大

N,M≤30

我们定义一个一个图最大点权独立集{S},{S}中的点要满足点权和最大并且两两没有连边

很容易发现可以黑白染色,即可以构建二分图

我们知道,独立集和覆盖集是互为补集的

那么最大点权独立集=所有点权-最小点权覆盖集=所有点权-最小割=所有点权-最大流

建图:

源点S连接所有黑色点,容量为点的权值

所有白色点连接汇点T,容量为点的权值

相邻的黑白格子之间连容量为正无穷的有向边

dinic求最大流即可

这个问题主要是看能不能转化

总结

网络流的概念比较多,要熟练掌握

考察网络流并不是考裸题,而是会考怎么建模

关键是有些题怎么看都不太像是网络流的题……

这就要看建模的能力了

但首先还是要好好把算法练熟了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: