8.21上课感悟

2 篇文章 0 订阅
2 篇文章 0 订阅

下午讲网络流……
尽管第一次学,但感觉还是比较不错的,学到很多东西

概念

我们定义  G=(V,E,C) 为一个有向图.  C 表示边的最大流量
必须时刻保证没有一条边的流量大于它的最大流量,也不能为负
定义源点  S 和汇点  T ,表示流量都从源点入,都从汇点出
除了源点和汇点之外,其他点不能储存流(就是流进多少,就流出多少)
可行流:
我们定义  flowu,v 表示从  u  v 的边中的流量
那么可行流必须满足两个条件:
1.  0flowu,vCu,v
2. flowu,v=flowv,u (即流进多少,流出多少)
这时  flow 就是  G 的可行流
网络流的对称性:  flowu,v=flowv,u
网络的流:
我们定义 ω=flowS,iflowi,s=flowi,TflowT,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[n]) break;//如果找不到增广路,说明求解完毕
        maxflow+=mn[n];
        for(int tmp=n;tmp!=1;tmp=pre[tmp])
            flow[pre[tmp]][tmp]+=mn[n],flow[tmp][pre[tmp]]-=mn[n];//调整网络,修改边和反向边的流量
    }
    return maxflow;
}

反向边的过程可能比较难以理解,可以看看网上其他人的讲解
dinic算法后续再讲,是对EK算法的改进
最后再提一个东西,就是最大流-最小割定理
往往要求最小割的时候直接可以求最大流

相关习题

1.狼抓兔子(题目戳这里
求最大流的一个问题
但是直接用dinic求最大流会T(接近O(N^3))
所以我们会想到最大流-最小割定理
最大流和最小割似乎可以相互转化?
这里写图片描述
将空白三角形的地方作为点,如图连边,求点S到点T的最短路即可
为什么?因为S-T的路径一定是一个切割
所以我们只要求出最小割就可以了
尽管用最小割来求最大流的比较少,主要是用最大流求最小割

2.方格取数问题
在一个  NM 的一个棋盘中,每一个方格里都有一个正整数权值
现在要在方格里取数,必须要满足取数的方格中两两没有公共边,并且要使得最后取出的权值总和最大
 N,M30
我们定义一个一个图最大点权独立集 {S} , {S} 中的点要满足点权和最大并且两两没有连边
很容易发现可以黑白染色,即可以构建二分图
我们知道,独立集和覆盖集是互为补集的
那么最大点权独立集=所有点权-最小点权覆盖集=所有点权-最小割=所有点权-最大流
建图:
源点S连接所有黑色点,容量为点的权值
所有白色点连接汇点T,容量为点的权值
相邻的黑白格子之间连容量为正无穷的有向边
dinic求最大流即可
这个问题主要是看能不能转化

总结

网络流的概念比较多,要熟练掌握
考察网络流并不是考裸题,而是会考怎么建模
关键是有些题怎么看都不太像是网络流的题……
这就要看建模的能力了
但首先还是要好好把算法练熟了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值