二分图

二分图

定义:一张图的 \(N\) 个节点可以分为 \(A,B\) 两个非空集合,满足同一个集合中的任意两个点没有连边

集合 \(A,B\) 分别叫做二分图的左部右部,如图所示:

二分图的判定

交替染色,只有相邻的点颜色不一样时才可能是二分图,

定理:二分图一定不存在奇环(易证)。

判定:搜索 \(dfs\)\(bfs\) 都行。

bool dfs(int u, int fa, int color) 
{
    col[u] = color; //给当前结点染色
    for (int i = head[u]; i; i = e[i].nxt) 
    {
        int v= e[i].tv;
        if (v== fa) continue;
        if (col[v] == color)
            return 0; // 子结点有颜色且与当前结点染色相同
        if (col[v] == 0 && !dfs(v, u, 3-color))
            return false; // 尝试染色失败
    }
    return true;
}
bool work()
{
  for (int i = 1; i <= n; i++) 
  {
      if (col[i] == 0) 
       {
          col[i] = 1; // 用1和2染色
          if (!dfs(i, 0, 1)) 
            return 0;
      }
  }
  return 1;
}

二分图的最大匹配

二分图的匹配:找出一个边集 \(M\),使任意两条边没有公共端点。属于 \(M\) 的边叫 匹配边,其端点叫 匹配点

交错路:从一个 非匹配点出发,依次经过匹配边,非匹配边……的一条路径。

增广路:从一个 非匹配点 出发,走 交错路,到达另一个 非匹配点 的路径。

增广路的性质

  1. 增广路上的边数为奇数。

  2. 路径上第 \(1、3、5……\) 条边为非匹配边,第 \(2、4、6……\) 条边为匹配边,所以非匹配边数量比匹配边数量多一。

  3. 我们从一个非匹配点出发走增广路,这条路径上的匹配边构成一个 匹配 ,这时对所有边进行取反(匹配变非匹配,非匹配变匹配),得到新的匹配比原来那个长度多一。

匈牙利(叙利亚,lyx,intr)算法

求最大匹配可以看做是一个舞蹈队的人分成了两个集合,给点集1中的点从点集2中找舞伴,点集1中的点都是男的,点集2中的点都是女的,每个人都有若干个意向的舞伴。

男找女,如果女没有舞伴,直接匹配。如果女有舞伴,那么考虑这名舞伴能不能妥协换一个,把当前的女伴让出来。

也就是根据增广路的性质看看能不能走出一条更长的增广路,然后取反状态。

bool mp[N][N],vs[N*N];
bool dfs(int u)
{
	for(int i=0;i<n;i++) if(!vs[i]&&mp[u][i])
	{
		vs[i]=1;
		if(!mt[i]||dfs(mt[i]))//这里dfs的是match
		{
			mt[i]=u;
			return 1;
		}
	}
	return 0;
}
int intr()
{
	int res=0;
	memset(mt,0,sizeof(mt));
	for(int i=0;i<n;i++)
	{
		memset(vs,0,sizeof(vs));
		if(dfs(i)) res++;
	}
	return res;
}

最小顶点覆盖

顶点覆盖:设点集 \(V^{'}\),图中每一条边至少有一个顶点在集合 \(V^{'}\)

最小顶点覆盖:顾名思义,使 \(V^{'}\) 中的元素尽量少。

结论一:最小顶点覆盖=最大二分图匹配

(感性理解:二分图任意两条边之间都没有公共点,所以点的覆盖作用被最大化了)

最大独立集

独立集:点集 \(V^{'}\) 中任意两个点之间没有连边。(例如二分图的左部和右部)。

结论二:最大独立集=总点数-最小顶点覆盖=总点数-最大二分图匹配

(感性理解:最小顶点覆盖保证每一条边至少有一个点被选,把这些点去掉相当于去掉所有边,剩下的点就没有边了)

总结

关于建图

二分图看起来只是把图分成了两部分,但其实这两部分可以抽象的作为 冲突 的两端。

如果两者之间有冲突则建边,没有冲突则属于二分图的同一部,长、常用来求 不包含冲突的最大集合,也就是最大独立集。

关于双向边

最大二分图匹配的流程是由左部找有部的点,其实是有向图。

一般我们希望二分图的左右部分别代表不同的意义,构成有向图,如男女,行列……

但更多时候题目没有明确给出左部和右部,虽然这个图仍具有二分图的性质,我们也不知无向边两端哪个是左部,

我们在连双向边时会将所有点各在左右部放一次,也就是建两条边,让这个双倍的点集自发的跑出二分图的形状(前提它是二分图)

这时就会出现重复的边,也就是我们跑出的最大二分图匹配其实是双向边的,也就是二倍。

所以最后答案要除二。

关于行与列

在有关地图放置的题目中我们常将行与列作为 冲突 ,跑二分图最大匹配。

但如果地图中有一些 障碍物 呢?这时冲突依然可以成立,只是 的定义不同了。

我们以题为例:

放置机器人

这道题冲突是明显的,两个机器人不能处于同一行或同一列(先不考虑障碍),

这时我们对行与列的定义是这样的

性质1. 同一行(或列)中只能放一个。

性质2. 不同行(或列)之间不会有影响。

现在,让我们加入障碍物。障碍物会把一行(或列)分成若干个部分,

每个部分依旧满足 性质1 ,每一个 部分,只能放一个。

性质2 呢?也满足!

于是 “行” 和 “列” 的定义扩大了,我们可以通过记录 “分块” 的方式重组行列。

照常跑 \(intr\) 就行了。

posted @ 2024-05-19 13:21  ppllxx_9G  阅读(10)  评论(0编辑  收藏  举报