网络流笔记
几个概念:
记图G = (V, E)
匹配:在G中两两没有公共端点的边集M⊆E (我们可以这样理解, 所有的点两两匹配, 自然所有的匹配点之间的边都没有公共点了,最大匹配就是最多能有多少点匹配,最小匹配没有意义)
边覆盖:G中任意顶点都是边F中某条边的端点的边的集合F⊆G (我们可以这样理解, 用一些边把顶点连起来)
独立集:在G中两两互不相连的顶点集合M⊆V (我们可以这样理解, 选出一些没有邻居的点)
顶点覆盖:G中任意边都至少有一个端点属于点集M, M⊆V (我们可以这样理解, 选一些点, 把边都覆盖了)
1
对于不存在孤立点的图, |最大匹配|+|最小边覆盖| = |V|
我们来证明一下:
首先我们有了最大匹配F⊆E
那么我们每次选一条边加入F, 这条边最多联通一个顶点, 如果联通了两个, 那么F就不是最大匹配了。
这样的话, 我们最少需要|V| - 2*|F| 条边覆盖所有顶点 (因为F中每条边都覆盖了两个顶点)(我们每次选一条边, 如果顶点没有全部被覆盖, 每次肯定能覆盖一个新的点, 这挺显然的) 所以我们可以知道|最小边覆盖| = |V| - 2*|F| + |F| = |V| - |F| 所以|最大匹配| + |最小边覆盖| = |V| - |F| + |F| = |V| 证毕
2
|最大独立集|+|最小顶点覆盖| = |V|
首先我们知道, 任意独立集F中每个顶点相邻的边另一侧肯定连接了一个点u∈∁UF(我们想一下, 每条边必定连接了两个顶点, 而且最大独立集中点相邻的边不可能连接两条同时∈F的边, 要不就不是最大独立集了, 那么这些点肯定属于∁UF)我们再任选一条边, 这条边两端的顶点肯定至少有一个顶点u∉F, 也就是u∈∁UF,那么我们就知道了,∁UF中的点能覆盖任意一条边,也就是说∁UF是G的一个顶点覆盖。因为|F|+|∁UF|=|V| 于是我们可以得出|V|-|F|=|∁UF|。
设∁UF=M,也就是说G的顶点覆盖M有|M|=|V|-|F|。因为|F|为G的任意顶点覆盖,所以我们可以得出:F是G的顶点覆盖-->M是G的边覆盖 因为|M|=|V|-|F| 所以当且仅当F为G最大独立集时M为G的最小顶点覆盖 证毕
以上问题于是就可以互相转化
3
|最大匹配|=|最小顶点覆盖| 二分图中成立
因为最大匹配和最大流有关,因此上述四个问题都可以求解了,因此衍生出了很多题目
4
补充一些关于二分图的知识,二分图主要应用为二分图匹配
1.完美匹配:设|F|为图G=(V, E)的一个匹配。 当且仅当2*|F|=|V|时F为图G的一个完美匹配
2.解法:(1)最大流 (2)匈牙利
匈牙利算法
bool dfs(int u) { used[u] = 1; for(int i = head[u]; i; i = e[i].nxt) if(!match[e[i].to] || (!used[match[e[i].to]] && dfs(match[e[i].to]))) { match[e[i].to] = u; match[u] = e[i].to; return true; } return false; } void solve() { int ans = 0; for(int i = 1; i <= n; ++i) if(!match[i]) { memset(used, 0, sizeof(used)); if(dfs(i)) ans++; } printf("%d\n", ans); }
重点在于理解如何实现dfs过程
对于每个点,如果没有被匹配过,那么我们就要像一个办法让它匹配。
于是开始dfs,当前点为u,它的后继点为v。当v没有被匹配过,或者v的后继匹配成功了,也就是把v空出来了,那么说明u的匹配成功,match[u]=v,match[v]=u return true 如果所有后继都不可以匹配或者腾出位置,就返回false。used数组是记录当前这个点是否被dfs过,如果dfs过,说明没有dfs这个点的意义。因为我们每次只新加入匹配一个点,因此只要腾出一个位置,那么就是成功的。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
那么我们需要练习一下
最近做了些网络流
网络流24题*5
bzoj 1412 (最小割)
最小割:s->1 1->2 1->0 0->2 2->T
因为我们要把这些点分成两个集合,一些点是羊的范围,一些点是狼的范围,因为要把图分成若干个块,所以空地和空地也要连
比如说
4 1
1
0
0
2
空地不连就炸了
bzoj 1497(最小割,也是最大权闭合子图)
这道题是个很有意思的模型
建图:ans=sigma(1,m,c[i])
ins(s,顾客,c) ins(顾客,塔,inf) ins(塔,T,p)
然后ans-最小割
若不割左侧 相关右侧都要割
若不割右侧 相关左侧都要割
为什么是对的呢?因为我们想要满足一个人,必须买两座塔,那么也就是把塔到T的两条边割掉,如果不满足,那么就把s和顾客的边割掉,对于一个顾客,他到T的路径只有两条,如果我们只割掉一条,剩下两条不割,那么很明显,这个图还可以增广,如果我们割掉两座塔,那么自己的c就肯定不会割掉了,因为到T的路径已经被堵掉了,如果把c割掉了,那么两座塔就可割可不割,因为至少这条道路被割掉了