学习笔记 二分图

二分图的定义

  如果一张无向图的 N 个节点(N ≥ 2) 可以分成 A,B 两个非空集合,其中A∩B=Ø,并且在同一个集合内的点之间都没有边相连,那么称这张无向图为一张二分图。A,B 分别称为二分图的左部和右部。

二分图的一些性质:

  1.图中不存在奇环。(证明,二分图构成环,必然是 A-B-A 之类的,此时环的长度必然为偶数。证毕。)

  2.一张无向图是二分图,当且仅当图中不存在奇环。

  关于性质2的证明,我们可以考虑使用染色法。首先,若图中存在奇环,则不可能是二分图。当图中不存在奇环,此时我们对图中的每个点用黑白两种颜色标记,黑色表示二分图的左部点,白色表示二分图的右部点。当一个节点被标记后,它的所有相邻节点标记成与它相反的颜色。因为不存在奇环,对于一个不是环的路径,必定可以做到黑白黑白黑白……这样的标记,满足二分图的定义。而对于一个偶环,我们也能够做到黑白黑白黑这样的标记(可以画图尝试)。因此当不存在奇环是,这个无向图就是二分图。

二分图的判定:

  我们仍然可以用染色法。若标记过程中产生冲突,说明存在奇环,该图不是二分图。若标记成功,说明不存在奇环,该图是二分图。染色法一般基于深度优先遍历实现,时间复杂度为(N+M),其代码如下:

复制代码
int flag=1;
void dfs(int x,int color){
    v[x]=color;//赋值
    for(int i=head[x];i;i=Next[i]){
        int y=ver[y];
        if(!y) dfs(y,3-color);
        else if(v[y]==color) flag=0; 
    }
}
复制代码

二分图最大匹配(此处参考lyd的蓝书)

  定义:"任意两条边都没有公共端点"的边的集合被称为图的一组匹配。在二分图中,包含边数最多的一组匹配被称为二分图的最大匹配。

  对于任意一组匹配 S ( S 是一个边集),属于S的边被称为"匹配边",不属于 S 的边被称为“非匹配边”。匹配边的端点被称为“匹配点”,其他节点被称为“非匹配点”。

增广路

  定义:如果在二分图中存在一条连接两个非匹配点的路径 path,使得非匹配边与匹配边在 path 上交替出现,那么称 path 是匹配 S 的增广路,也称交错路

  性质:1.长度 len 是奇数;2.路径上第奇数条边是非匹配边,第偶数条边是匹配边。

  增广路的推论:二分图的一组匹配 S 是最大匹配,当且仅当图中不存在 S 的增广路。

  浅析一下:基于增广路的性质,如果我们把路径上的所有边的状态取反,原来的匹配边变成非匹配边,原来的非匹配边变成匹配的,那么得到的边集 S' 仍然是一组匹配,并且匹配边数增加了1。因此当存在增广路是,必定能找到一组更优的匹配。证毕。

匈牙利算法(增广路算法)

  用途 :计算二分图最大匹配

  主要过程:

  1.设 S=Ø,即所有边都是非匹配边;

  2.寻找增广路path,把路径上所有边的匹配状态取反,得到一个更大的匹配 S';

  3.重复第2步,直至图中不存在增广路。

  对于该过程的实现,我们可以枚举每一个左部点 x ,尝试为每个 x 寻找一个匹配的右部节点 y。

  找到的这个节点 y 必须满足以下两个条件之一。

  1. y 本身就是非匹配点。 2. y 已经与左部点 x' 匹配,但能从 x' 出发能找到另一个右部点 y'。

实现方法如下:

复制代码
bool dfs(int x){
    for(int i=head[x];i;i=Next[i]){
        if(!vis[y=ver[i]]){
            vis[y]=1;
            int t=match[y];
            if(!t||dfs(t)){
                match[y]=x;
                return true;
            }
        }
    }
    return false;
}
for(int i=1;i<=n;++i){//在main函数中 
    memset(vis,0,sizeof(vis));
    if(dfs(i)) ans++;
}
复制代码

  匈牙利算法的正确性基于贪心策略,它的一个重要特点是:当一个节点成为匹配点后,至多因为找到增广路而更换匹配对象,但是绝对不会变成非匹配点。

对面每个左部节点,寻找增广路最多便利整张二分图一次。因此,该算法的时间复杂度使O(NM)。

建模

  二分图匹配的模型有两个要素:1.节点能分成独立的两个集合,每个集合内部有0条边;2.每个节点只能与一条匹配边相连。

完备匹配 

  给定一张二分图,其左部、右部节点数相同,均为N个节点。如果该二分图的最大匹配包含N个匹配便,则称该二分图均有完备匹配。

二分图最小点覆盖

  给定一张二分图,求出一个最小的点集 S,使得图中任意一条边都有至少一个端点属于 S。这个问题被成为二分图的最小点覆盖,简称最小覆盖。

König定理:二分图最小点覆盖包含的点数等于二分图最大匹配包含的边数(证明略

二分图的最大独立集

  给定一张无向图 G =(V,E),满足下列条件的点集 S 被称为图的独立集。

  1. S ⊆ V 

  2. ∀ x,y ∈ S , (x , y) ∉ E

  通俗的讲,图的独立集就是“任意两点之间都没有边相连”的点集。包含点数最多的一个就是图的最大独立集。

对应地,“任意两点之间都有一条边相连”的子图被称为无向图的“团”。点数最多的团被称为图的最大团。

定理1:无向图G的最大团等于其补图G'的最大独立集。(正确性显然)

   注:G' = (V , E') 被称为 G=(V , E ) 的补图,其中 E'={(x , y) ∉ E } 。

定理2:设G是有n个节点的二分图,G的最大独立集的大小等于n减去最大匹配数。

证明:

  选出最多的点构成独立集

  < = > 在图中去掉最少的点,使剩下的点没有边

  < = > 用最少的点覆盖所有的边。

  因此,去掉二分图的最小点覆盖,剩余的点就构成二分图的最大独立集。而最小点覆盖数等于最大匹配数,故最大独立集大小等于 n 减去最大匹配数。

  证毕。

有向无环图的最小路径点覆盖

  给定一张有向无环图,要求用尽量少的不相交的简单路径,覆盖有向无环图的所有顶点(也就是每个顶点恰好被覆盖一次)。这个问题被称为有向无环图的最小路径点覆盖,简称“最小路径覆盖”。

  设原来的有向无环图为 G = (V , E),n=|V|。把 G 中的每个点 x 拆成编号为 x 和 x+n 的两个点。建立一张新的二分图, 1~n作为二分图左部点,n+1~2n 作为二分图右部点,对于原图的每条有向边(x , y),在二分图的左部点 x 和右部点 y+n 之间连边。最终得到的二分图称为 G 的拆点二分图,记为 G2。

定理:有向无环图的最小路径点覆盖包含的路径条数,等于 n 减去拆点二分图 G2 的最大匹配数。

证明:

  在有向无环图 G = (V , E)的最小路径覆盖中,对于任意 x ∈ V ,因为路径不相交,所以 x 的入度和出度都不超过1。因为每个节点都被覆盖,所以 x 的入度和出度至少有一个是1。

  因此,最小路径覆盖中的所有边,在拆点二分图 G2 中构成一组匹配。最小路径覆盖中每条边 (x , y) 的起点 x 与而二分图每条匹配边 (x , y+n) 的左部点 x 是一一对应的。

  特别地,对于每条路径的终点 t,因为 t 没有出边,所以在二分图中,t 匹配失败。即路径的终点和二分图左部的非匹配点是一一对应的。

  路径覆盖包含的路径条数最少

  <=> 路径的终点数(出度为 0 的点数)最少

  <=> 二分图左部非匹配点最少

  故 G 的最少路径覆盖的路径数等于 n 减去拆点二分图 G2 的最大匹配数。

  证毕。

最小路径可重复点覆盖

  给定一张有向无环图,要求用尽可能少的可相交的简单路径,覆盖有向无环图的所有顶点(也就是一个节点可以被覆盖多次)。这个问题被称为有向无环图的最小路径可重复点覆盖。

  在最小路径可重复点覆盖中,若两条路径 …->u->p->v->…和…->x->p->y->…在点 p 相交,则我们在原图中添加一条边 (x , y),让第二条路径直接走 (x , y),就可以避免重复覆盖点p。

  进一步地,如果我们把原图中所有间接连通的点对 x , y 直接连上有向边 (x , y),那么任何“有路径相交的点覆盖”一定可以转化成“没有路径相交的点覆盖”。

  综上所述,有向无环图 G 的最小路径可重复点覆盖,等价于先对有向图传递闭包,得到有向无环图 G',再在 G' 上求一般的(路径不可相交的) 最小路径点覆盖。

posted @   LikC1606  阅读(191)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示