网络流笔记

几个概念:

记图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);
}
View Code

重点在于理解如何实现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割掉了,那么两座塔就可割可不割,因为至少这条道路被割掉了

 

posted @ 2017-03-02 23:32  19992147  阅读(159)  评论(0编辑  收藏  举报