[学习笔记]二分图

1.定义

可以把图中的点分成两部分,使得每部分内部两两点之间没有连边。

2.二分图判定

没有奇环的图,或者能够黑白染色的图。

3.一些东西:

①匹配

边的子集,两两边没有公共点。

②覆盖

点的子集使得每条边至少和一个点关联

③支配集

点的子集,使得每个点要么自己在集合里,要么和一个集合里的点关联。

④独立集

点的集合,使得任意点之间没有连边

4.完美匹配

①定义:最大匹配中的每个点都是匹配点

②Hall定理(完美匹配的充分必要条件)

选择任意的左部点S个,把所有这S个点关联的K个右部点取出来,一定有|S|<=|K|

证明:

必要性:有完美匹配的二分图必然满足Hall定理。假设存在S>K,那么这S个点不可能都被选上。

充分性:假设二分图满足Hall定理,但是最大匹配不是完美匹配。

所以,能找到一个左部点的非配点a1,开始Hungary。由于Hall定理,非匹配点一定有连边。右部点b1一定是匹配点。否则有增广路。

然后访问右部点b1的左部匹配点a2,a2一定还有另外的一个关联的点b2。这个点一定是非匹配点,否则就从a1到b2有一条增广路。

b2又有一个左部匹配点a3.。。。。。。

发现,点数会无限增长下去。

例题:

也是一个多重匹配的推广

「BZOJ3693」圆桌会议

Hall定理的好处是,我们可以通过另外一种方法考虑有没有完美匹配。并不一定要建图跑二分图了

考虑指向右部点的总点数大于∑ai,也就意味着任意一个右部点的区间[p,q]完全包含的所有[li,ri]区间的ai和和不能大于[p,q]的长度p-q+1

任意,只用考虑[lj,ri]的区间,按照右端点排序,不断枚举右端点,线段树维护所有左端点到当前r的s+li-1值,前缀加,前缀求max

5.Konig定理

最小点覆盖=最大匹配

证明:由于匹配边没有公共点,所以最小点覆盖的下界是最大匹配。

我们只需要证明存在一种构造方法使得达到下界。

完成最大匹配后,从每个左部非匹配点找增广路(一定会失败),把所有访问过得左部点和右部点打上标记。

左部非标记点和右部标记点构成了最小点覆盖

因为:

1.每个左部非匹配点都被打上了标记。

2.每个右部非匹配点都没有打上标记。否则找到一条增广路。

3.每对匹配点要么都打上标记,要么都没有。因为访问过其中一个点,必然能通过pre找到另一个点。

所以,其实是每个匹配边选择一个点。和最大匹配相等。

再证是覆盖:

1.每个匹配边被覆盖。

2.左非匹配,右匹配。从这个左部非匹配点出发,一定会标记右部这个匹配点。

3.左匹配,右非匹配。这个左部点一定没有打上标记,否则会找到这个右部非匹配点找到增广路。

4.不存在两边都是非匹配点。否则本身就有增广路。

证毕。

最大独立集=N-最小点覆盖

证明:最大独立集下界是这个。因为一定存在构造方法:即把所有最小点覆盖抠掉。

上界也是这个。否则要把一个覆盖点加入独立集。如果还是独立集的话,那么最小点覆盖就可以更小。矛盾。

证毕。

6.最小链覆盖(DAG中)

点不能相交:拆点。把原图中原来的边(u,v),从u+连到v-。然后最小链覆盖就是原图点数-最大匹配。

证明:开始每个点都是一个链,每合并两个点(二分图中找一条匹配边),就可以减少一。而且,匹配本身不能有公共点,符合点不能相交

点可以相交:拆点。传递闭包。能到达的点二分图上连边。然后转化成点不能相交。

证明:可以相交就是对于类似叉号的图有帮助。然后我们就好似建了一座天桥,可以直接到达,不用经过交叉点。

最小链覆盖的方案求法:

把二分图的匹配边还原一下即可。


upda:2019.5.11

其实不用传递闭包,毕竟是DAG,直接反向topo,向所有后继连边即可。O(n^2)

7.Dilworth定理和最长反链

最长反链:其实是一个点的集合。集合中两两之间不可达。

最长反链=最小链覆盖。证明不会。

构造最长反链:

求最小链覆盖。从那个二分图匹配中,找最大独立集,选择(u+,u-)都在独立集的u,就是最长反链。

证明不会。

例题:

就好比最大匹配和最小点覆盖、最小点覆盖和最大独立集、最大流和最小割的关系。

都是对偶问题,哪个更好做,更符合题意建模,就做哪一个。

导弹拦截第二问。可以看做DAG。最小不下降子序列覆盖=最长上升子序列长度。因为这个就是反链。两两不可达。

[CTSC2008]祭祀

第三问要找能在最长反链中的。枚举点,抠掉这个点的所有出点和入点,新图找最长反链len。

如果len=ans-1,那么把这个点加回去,最大独立集肯定可以+1,那么就是可行的点。

 由于最长反链是ans,所以不存在去掉之后len大于等于ans的情况(什么证明啊这是)。

 [TJOI2015]组合数学

网格图是DAG,求最小链覆盖,每个点要重复多次覆盖。没法做。

Dilworh定理合理外推可以得到:就是带权最大反链

最大反链这里就是右上-左下的一些点。f[i][j]递推即可

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
    char ch;x=0;bool fl=false;
    while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);
    (fl==true)&&(x=-x);
}
template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('
');}

namespace Miracle{
const int N=1005;
ll f[N][N],a[N][N];
int n,m;
int t;
int main(){
    int t;
    rd(t);
    while(t--)
    {
        rd(n);rd(m);
        memset(f,0,sizeof f);
        for(reg i=1;i<=n;++i){
            for(reg j=1;j<=m;++j){
                rd(a[i][j]);
            }
        }
        ll ans=0;
        for(reg i=1;i<=n;++i){
            for(reg j=m;j>=1;--j){
                f[i][j]=max(f[i-1][j],max(f[i][j+1],f[i-1][j+1]+a[i][j]));
                ans=max(ans,f[i][j]);
            }
        }
        printf("%lld
",ans);
    }
    return 0;
}

}
signed main(){
    Miracle::main();
    return 0;
}

/*
   Author: *Miracle*
   Date: 2019/3/31 17:05:23
*/
View Code

upda:2018.11.5

9.有完备匹配的二分图可行边和必须边

与最大匹配有关。

给边定向。

匹配边右-左

非匹配边左-右

Tarjan判SCC

对于边(x,y)

如果c[x]==c[y]那么(x,y)是可行边。

如果(x,y)是匹配边,并且c[x]!=c[y]那么(x,y)是必须边

原文地址:https://www.cnblogs.com/Miracevin/p/9806475.html