首页 > 其他分享 >二分图

二分图

时间:2023-08-17 16:13:34浏览次数:28  
标签:二分 head 匹配 int st maxn

定义

一张无向图,如果可以将节点分成两个部分,使得两个部分内部没有任何边相连,也就是每条边的端点都分属两个部分,就可以说这张图为二分图。

判定

当且仅当图中不存在长度为奇数的环时,这一张图为二分图。

因为显然每经过一条边都会到达另一个部分,以此类推,经过奇数条边后比不可能还在一开始的部分。

最大匹配

选择一些边,使得任意两条边都没有公共的端点,我们就可以称这些边为图的一组匹配,边数最多的一组我们称为最大匹配。

接下俩我们称被选中的边为匹配边,匹配边的端点为匹配点。如果二分图中存在一条路经连接两个非匹配点,使得匹配边与非匹配边在路径上交替出现,那么可以将此路径称为这组匹配的增广路。

根据定义可知,当我们将增广路上的匹配边变为非匹配边,非匹配边变为匹配边,新的匹配边仍然能够构成一组匹配,并且边数增加了1。

匈牙利算法:

用于计算二分图最大匹配,主要就是找增广路。算法会依次尝试为每一个二分图中的左部点\(x\)寻找一个匹配的右部点\(y\),流程如下:
从一个左端点出发,一次遍历它的出边,会到达一个点\(y\),接下来我们就要判断点\(y\)的情况:
1.\(y\)没有匹配点,那么可以将\(y\)d的匹配点变为\(x\)。
2.\(y\)有匹配点\(z\),但是\(z\)可以寻找到新的匹配点。
对于点\(z\)我们可以重复上诉流程,知道寻找不到匹配点为止。

这样一来,如果一个点变为了匹配点,那么它永远不会变回非匹配点,即代表着,假如一个新的点变为了匹配点,那么总的匹配点数量肯定可以增加。

代码实现:模板题:P3386 【模板】二分图最大匹配

#include<algorithm>
#include<stdio.h>
#include<queue>
#define maxn 1005 
#define maxm 100005
using namespace std;
int n1,n2,m;
int head[maxn],to[maxm],nex[maxm],m1;
void add(int u,int v) {
	to[++m1]=v;
	nex[m1]=head[u];
	head[u]=m1;
}
int vis[maxn],match[maxn];
bool dfs(int now) {
	for(int i=head[now];i;i=nex[i]) {
		int st=to[i];
		if(!vis[st]) {
			vis[st]=1;
			if(!match[st] || dfs(match[st])) {
				match[st]=now; return true;
			} 
		}
	}
	return false;
}
int main() {
//	freopen("P3386.in","r",stdin);
//	freopen("P3386.out","w",stdout);
	scanf("%d%d%d",&n1,&n2,&m);
	for(int i=1;i<=m;i++) {
		int u,v; scanf("%d%d",&u,&v);
		add(u,v+n1),add(v+n1,u);
	}
	int ans=0;
	for(int i=1;i<=n1;i++) {
		for(int j=1;j<=n2+n1;j++) {
			vis[j]=0;
		}
		if(dfs(i)) ans++;
	}
	printf("%d\n",ans);
	return 0;
}

标签:二分,head,匹配,int,st,maxn
From: https://www.cnblogs.com/1n87/p/17636326.html

相关文章

  • 二分图浅学
    前言:由于NOI大纲中对二分图的要求仅停留在判定,所以本文主要讲解二分图染色。二分图指:一张图可以分成两个集合,使得两个集合内部没有边相连,边在两个集合之间。判定二分图的充要条件是:不存在奇环。那么我们可以对于整张图交替染色,如果发现矛盾,存在奇环;否则说明不存在奇环。其实......
  • 杭电23多校第九场Capoo on tree(二分+树链剖分+可持久化线段树)
    2023HDU多校9__Capooontree(二分+树链剖分+可持久化线段树)题目链接Solution\(Hint1\)考虑如何进行对某一相同点权的所有点进行点权\(+1\)操作,如果我们建立权值线段树,那只需要将权值为\(x\)的点并入权值\(x+1\)即可,但是这样就算我们建立以节点编号为版本的可持久化线段树,也是......
  • D: Space Golf[二分+数学]
    题意大概是给你一个小球,完全弹性碰撞,有若干高度的板子,问从0-target的最小合速度是多少。完全弹性碰撞,意味着给定一个初始速度,运动轨迹将是一个抛物线的不相交的等距(d/(i+1))右移。i是弹跳次数而确定好水平速度后,球的落点就是确定的,那么当y能过的时候,任何大于y的高度也能过去。......
  • 704. 二分查找、27. 移除元素
    704.二分查找、27.移除元素704.二分查找力扣题目链接(opensnewwindow)给定一个n个元素有序的(升序)整型数组nums和一个目标值target,写一个函数搜索nums中的target,如果目标值存在返回下标,否则返回-1。示例1:输入:nums=[-1,0,3,5,9,12],target=9输出:4......
  • 二分图的一些概念
    二分图:将图中的顶点分为两个集合X和Y,X与Y集合没有交集,并且各自集合内的点没有边相连,X集合与Y集合形成边二分匹配:在二分图的基础上,XY两个集合所形成的边集中的子集M,M中的任意两条边没有公共的顶点最大匹配:当M中的边数达到二分图的上限时称为最大匹配完美匹配:二分图中的所有顶点......
  • [二分图] 学习笔记
    定义无向图可以分成两个点集,集合内的点不相连通,不允许存在奇环//二分图的判定#include<bits/stdc++.h>usingnamespacestd;constintN=1e3+10,M=2e6+10;struct{ intto,next;}e[M];inttop,h[N],color[N],n,m;voidadd(intx,inty){ e[++top]......
  • HDU 3829 Cat VS Dog 猫和狗(二分图)结题报告
    听学长说这道题很ex,但是思路想到的话还是挺简单的。可能是受上一道题(放置机器人)的启发,也是找互相冲突的点连线。但是并不是完全一样(废话)放置机器人那道题是找到冲突点连线后直接求最大匹配即可。这道题稍微把思路变换一下,求出最大完美匹配数\(n\)后,说明有\(n*2\)个人的喜好......
  • 704. 二分查找
    参考链接:https://programmercarl.com/0704.二分查找.html#思路给定一个n个元素有序的(升序)整型数组nums和一个目标target,写一个函数搜索nums中的target,如果目标值存在,就返回下标,否则返回-1。tips:假设nums所有元素不重复n在[1,10000]之间nums的每个元素都将在[-9999,9999]之......
  • 二分
    二分介绍相信大家小时候都玩过猜数字的游戏,一般来说,大家都是从中间开始猜,比如猜0~100之间的整数,先猜50,小了再猜75,大了再猜35。我们在玩这个游戏时就使用了二分这个思想,在算法竞赛中,我们对具有单调性的问题便可以使用二分,是一种非常好用的算法,但是二分里面的坑也非常多,稍有不慎便......
  • C++STL库 二分查找,以及对set集合进行二分查找,来源于”leetcode7022. 限制条件下元素之
    C++的头文件<algorithm>中有用于二分查找的函数,lower_bound()、upper_bound()以及binary_search():lower_bound():返回大于等于目标值的第一个位置upper_bound():返回大于目标值的第一个位置,binary_search():若目标值存在则返回true,否则返回false参数列表:(起始位置,结束位置,目标值) ......