二分图学习笔记
反正就给自己看,那么就随便写写
吐槽一下CPP为什么这么迟才教二分图
一个图是二分图,那么这个图就一定可以分成两部分,这两部分的点一定不会与自己的只一部分直接相连
二分图的判断非常水,直接黑白染色就可以了
只要没有奇环(我tm打qihuan都比打jihuan要快)就可以了
然后就会有很多的板子题了
然后就是二分图的的最大匹配问题
解决二分图的最大匹配问题,一般使用匈牙利算法
匈牙利算法用于解决二分图的最大匹配和最大权匹配的问题
其实就是找到很多的没有匹配的路,然后让没有匹配的路和匹配的路连在一起,然后翻转过后让长度增加,这就是基本思路。
那么我们都从左边开始找,然后通过找一个点来跳转,每次都只更新一条边,从1到n都更新一遍就能找到最大匹配了
代码:
bool dfs(int p){
if(vis[p])return false;
vis[p]=1;
for(int i:e[p]){
if(!a[i]||dfs(a[i])){
a[i]=p;
return true;
}
}
return false;
}
void solve(){
for(int i=1;i<=n;i++){
memset(vis,0,sizeof(vis));
if(dfs(i))ans++;
}
}
补充几个相关的性质
Kőnig 定理说明了二分图中,最小点覆盖中的顶点数量等于最大匹配中的边数量。
证明显然?
然后是二分图上最大独立集
这个可以根据Kőnig 定理推出来,最大独立集就是所有点数量减去最小点覆盖的数量
证明似乎也是显然的?
然后就可以用最大匹配的边数去求这些东西了
然后是有向无环图上的最小路径覆盖,其实路径数也是顶点数减去最大匹配
通过出边入边搞出二分图,然后就可以通过这个最大匹配来搞出几条长的路径,其它的不相连,就能够搞出来了
然后是最大权匹配问题
我们需要给每个节点 \(i\) 分配一个权值 \(l(i)\),对于所有边\((u,v)\)满足\(w(u,v)\le l(u)+l(v)\)。
在一组可行顶标下原图的生成子图,包含所有点但只包含满足 \(w(u,v)=l(u)+l(v)\) 的 \((u,v)\) 的子图称为相等子图。
显然可得定理:对于某组可行顶标,如果其相等子图存在完美匹配,那么,该匹配就是原二分图的最大权完美匹配。
那么我们就可以考虑从调整可行项标的角度入手
我们要让所有点都匹配上,所以我们考虑从每一个点开始枚举,直到找到可以匹配的情况
我们先把左边的(去匹配)的点找出来,然后把最大的边权设为值,枚举每一个点,如果都没法拓展,那么就把距离连接最接近的点找到,得到这个点的差值,然后让目前连接出来的这个图中,所有左边的点减去这个差值,右边的点加上这个差值,这样就维持了整个图的平衡,然后又可以继续连接,由于每次至少会连一个点,所以时间复杂度也是 \(O(n^3)\) 的。
那么直接就可以搞出来了哈哈哈我简直是一个天才
代码:
bool dfs(int p){
if(visx[p])return false;
visx[p]=1;
for(int i=1;i<=k;i++){
if(!visy[i]&&lx[p]+ly[i]==e[p][i]){
visy[i]=1;
if(!a[i]||dfs(a[i])){
a[i]=p;
return true;
}
}
else if(!visy[i])d=min(d,lx[p]+ly[i]-e[p][i]);
}
return false;
}
int km(){
memset(ly,0,sizeof(ly));
for(int i=1;i<=k;i++){
lx[i]=e[i][1];
for(int j=2;j<=k;j++)lx[i]=max(lx[i],e[i][j]);
}
memset(a,0,sizeof(a));
for(int i=1;i<=k;i++){
while(1){
memset(visx,0,sizeof(visx));
memset(visy,0,sizeof(visy));
d=2e9;
if(dfs(i))break;
for(int j=1;j<=k;j++){
if(visx[j])lx[j]-=d;
if(visy[j])ly[j]+=d;
}
}
}
int ans=0;
for(int i=1;i<=k;i++)ans+=e[a[i]][i];
return ans;
}
当然这个是求最大值的做法,最小值有个比较简单的方法是直接把边权搞成负数,属于是简单无脑了。
然后二分图的内容就差不多了哈哈,直接整完了,感觉CPP放的二分图都还算好写
那么再研究研究怎么建图吧
首先常见的是直接让你匹配两者关系的,直接建图就可以了
然后如果是普通图,但是有出度入度最多只有1的构造问题,那么也可以通过二分图的匹配来解决
我的天哪Sunday大人就这么水灵灵的写完了

浙公网安备 33010602011771号