二分图总结
作者:互联网
written on 2022-04-22
二分图的几种题型,总结如下:
- 二分图判定
染色法,用 dfs 对每个点进行染色,看看有没有矛盾的
bool check(int x)
{
for(int i=head[x];i;i=nxt[i])
{
int y=ver[i];
if(col[y])
{
if(col[y]!=oth(col[x])) return 0;
continue;
}
col[y]=oth(col[x]);
if(!check(y)) return 0;
}
return 1;
}
- 二分图最大匹配
匈牙利定理找增广路,对于左部的每一个节点 dfs 扫一遍(只用从左部到右部加单向边)
int mark[N];
bool vis[N];
bool dfs(int x)
{
for(int i=head[x];i;i=nxt[i])
{
int y=ver[i];
if(vis[y]) continue;
vis[y]=1;
if(!mark[y]||dfs(mark[y]))
{
mark[y]=x;
return 1;
}
}
return 0;
}
...
memset(mark,0,sizeof(mark));
int ans=0;
for(int i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis));
if(dfs(i)) ans++;
}
- 最小点覆盖
定义:对于一个二分图,找到最少的点,使得去掉这些点之后,可以使所有的边也被删除
定理:二分图的最小点覆盖等于其最大匹配
- 二分图的最大独立集
定理:二分图最大独立集的大小等于其最大匹配
- 有向无环图的最小路径覆盖
定义:在一个有向无环图中,找出最少的路径使之能覆盖所有的点
求法:对有向无环图进行拆点处理,将 \(1\) ~ \(n\) 视为二分图左部, \(n+1\) ~ \(2n\) 视为二分图右部,对于给定的边( \(x\) , \(y\) ),将x视为二分图左部的点, \(y+n\) (可直接记为 \(y\) ,不干扰)视为右部的点,连边,那么该有向无环图的最小路径覆盖即等于总点数减去拆点二分图的最大匹配。
对于一个路径覆盖,有如下性质:
1、每个顶点属于且只属于一个路径。
2、路径上除终点外,从每个顶点出发只有一条边指向路径上的另一顶点。
上面这一点很重要,是许多最小路径覆盖题目的背景基础。
稍需转化的例题传送门
PS:拆点好像是费用流的经典操作来着?
- 二分图的最大团
定义:在二分图中,找到一个最大的点集,使该点集中的所有不同部的点之间都有边相连
定理:二分图的最大团等于其补图的最大匹配
标签:二分,总结,return,int,路径,mark,col 来源: https://www.cnblogs.com/Freshair-qprt/p/16537700.html