20240718二分图

一.基础概念

1.定义:
如果一个图的所有顶点可以被分成两个集合U和V,使得每条边连接的两个顶点都分别属于两个不同的集合,那么这个图就是一个二分图(Bipartite Graph)。
2.性质:

  • 每个偶环都是二分图
  • 如果一个二分图中存在奇环,则它不是二分图。

二.霍尔定理

前言:在hloj上有这个内容,不知道是干嘛的,但是反正就是学了一下,觉得用处还挺大
附带一个将Hall定理的好博客:https://www.cnblogs.com/wenyutao1/p/17784455.html
1.内容:
对于一个二分图,不妨假设左部节点个数n小于等于右部节点个数m,那么这个二分
图存在完美匹配(也就是匹配数为n)当且仅当我们从左部选出任意k(1≤k≤𝑛)
个点,它们连向的右部点的数量不小于k。
2.推广:
对于一个左部点有n个,右部点m个,最大匹配大于等于n-a凼且仅当从左部分选任意个k个点(1≤k≤n)连向右部点的数量≥k-a
同时也相当于最大匹配=\(|S|-max_{S^{`}\subseteq S}(|S^{`}|-|tr(S^{`})|)\)
\(tr(S^{`})\)是与\(S^{`}\)相邻的点集

三.如何判定

1.染色法:
算法原理就是,用黑与白这两种颜色对图中点染色(相当于给点归属一个集合),一个点显然不能同时具有两种颜色,若有,此图就不是二分图

染色法判定二分图
bool dfs(int u,int c)
{
	color[u]=c;//当前点先染色
	for(int i=h[u];~i;i=ne[i]) 
	{
		int j=e[i];//对于这个点连接的所有的点
		if(color[j])//如果已经被染过色了
		{
			if(color[j]==c)
			  return false;
			//就需要判断一下,如果两点颜色一样,染色就冲突了
		}
		else 
		if(!dfs(j,3-c))
		  return false;
		//否则dfs去染下一个结点,赋予的颜色肯定要跟 c 不一样
		//3 - 1 == 2,3 - 2 == 1
		//同时传回染色成功与否的信息
	}
	return true;
}
bool check() 
{
	memset(color,0,sizeof color);//0 —— 未染色,1 —— 黑色,2 —— 白色
	for(int i=1;i<=n;i++)
	  if(color[i]==0)//一旦某个点没染过色,dfs去染色
		if(!dfs(i,1))
		  return false;//如果传回false显然失败,此图不是二分图
	return true;
	//否则true
}

O(m+n)的复杂度 ## 四.求最大匹配 匈牙利算法(求出二分图的最大匹配数): 满足 是二分图 这个前提,才能使用匈牙利算法

所谓 最大匹配数 的意思就是:

两个集合分别选一个点,这两个点之间有边就确认一段关系(一个集合中的两点 占有 另一集合中同一个点 是不合法的 一夫一妻(确信) ),最多的关系数量就是这张二分图的最大匹配

匈牙利算法求二分图匹配
bool find(int x)//标准匈牙利
{ 
	for(int j=1;j<=n;j++)
	  if(!st[j] and g[x][j])//x 点连向的所有点(因为是二分图,所以这些点都在右集合),如果存在边且没标记过
	  { 
		  st[j]=true;
		  //标记一下,防止多次遍历
		  int t=match[j];
		  //右集合中该点的匹配对象
    	  if(!t or find(t)) //没对象就可以和 x 匹配,有的话就让 t 尝试更改对象,能更改就和 x 匹配,不能就false
		  { 
		  	  match[j]=x;
			  return true;
		  }
	  }
	return false;
}
int main() 
{
	cin>>n;
	int ans=0;
	for(int i=1;i<=n;i++)//遍历左集合
	{ 
		memset(st,0,sizeof st);//每次都要重置标记
		if(find(i))
		  ans++;//一旦有一个匹配,数量就++
	}
	cout<<ans;
	return 0;
}


最坏情况会每个点遍历全部边一次,所以时间复杂度是O(nm)

但匈牙利算法还是很优秀的,大部分情况时间都比较小

如果想要更优秀的算法左转 网络流 吧,匈牙利匹配本质上还是网络流的一种特殊形式,网络流可以更好地解决此类问题。

posted @ 2024-07-18 09:12  Merlin·Lee  阅读(1)  评论(0编辑  收藏  举报