首页 > 其他分享 >二分图的匹配

二分图的匹配

时间:2023-12-08 15:13:19浏览次数:27  
标签:二分 std 匹配 int mid value include

定义

有点扩展域并查集的意思~

如果一张无向图的 \(N\) 个节点 \((n\geq 2)\) 可以分成 \(A,B\) 两个非空集合,其中 \(A\cap B = \emptyset\),并且在同一集合内的点之间都没有边相连,那么称这张无向图为一张二分图。\(A\)、\(B\) 分别称为二分图的左部和右部。

img

性质

  • 如果两个集合中的点分别染成黑色和白色,可以发现二分图中的每一条边都一定是连接一个黑色点和一个白色点。
  • 二分图不存在长度为奇数的环。
    • 因为每一条边都是从一个集合走到另一个集合,只有走偶数次才可能回到同一个集合。

二分图判定

定理

由性质可推出判定定理:

一张无向图是二分图,当且仅当图中不存在奇环(长度为奇数的环)。

方法

根据该定理,我们可以用染色法进行二分图判定。

大致思想为:

  1. 尝试用黑白两种颜色标记图中的节点。
  2. 当一个节点被标记后,它的所有相邻节点应该被标记为与它相反的颜色。
  3. 若标记过程中产生冲突,说明图中存在奇环。

基于 \(DFS\) 的伪代码,时间复杂度为 \(\text O(N + M)\)。

void dfs(int x, int color)
{
	赋值 v[x] <- color
    对于与 x 相连的每条无向边 (x,y)
        if v[y] = 0 then
            dfs(y, 3 - color);//因为只有1、2两种颜色,3-1 = 2, 3-2 = 1
    	else if V[y] == color
            判定该图 不是二分图,算法结束
}

在主函数中
	for i <- 1 to N
		if v[i] = 0 then dfs(i, 1)
    判定无向图 是二分图

例题

对最大冲突值二分答案。

把所有仇恨程度大于当前 \(mid\) 的罪犯分到两个集合(在这两个罪犯之间建边)。

这张无向图的节点需要被分成两个集合(两个监狱),并且集合内部没有边(同一个监狱内没有仇恨程度大于 \(mid\) 的罪犯)。所以,我们用染色法判定是否为二分图即可。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector> 
#include<cstring>

using ll = long long;

const int N = 2e4 + 10;
const int M = 1e5 + 10;

std::vector<int> v[N];

int vis[N];
int n, m;
ll l, r, mid;

struct Node{
	int x, y; ll value;
	Node(int _x, int _y, ll _v): 
		x(_x), y(_y), value(_v) {}
	Node() {}
	void read() {std::cin >> x >> y >> value; r = std::max(r, value);}
	void setMap(int t) {if (value > t) v[x].push_back(y), v[y].push_back(x);}
}query[M];

void init()
{
	std::cin >> n >> m;
	int x, y, t;
	for (int i = 1; i <= m; i++) query[i].read(); 
}

bool dfs(int x, int color)
{
	vis[x] = color;
	for (auto to : v[x])
	{
		if (vis[to] == 0) 
		{
			if (!dfs(to, 3 - color)) return false;
		}
		else if (vis[to] == color)
			return false;
	}
	return true;
}

bool check(int x)
{
	memset(vis, 0, sizeof(vis));
	for (int i = 1; i <= n; i++) v[i].clear();
	for (int i = 1; i <= m; i++)
	{
		query[i].setMap(x);
	}
	for (int i = 1; i <= n; i++)
	{
		if (vis[i] == 0)
		{
			if (!dfs(i, 1)) return false;
		}
	}
	return true;
}

int main()
{
 	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout.tie(nullptr);
	init(); 
	while(l <= r)
	{
		mid = l + ((r - l) >> 1);
		if (check(mid)) r = mid - 1;
		else l = mid + 1;
	}
	std::cout << r + 1;
	return 0;
}

二分图最大匹配

标签:二分,std,匹配,int,mid,value,include
From: https://www.cnblogs.com/kdlyh/p/17887202.html

相关文章

  • 多重条件判断,if与else的成对匹配问题
    今天刷题犯了一个错误,本来三个条件是互斥的,但想偷懒,直接将最后一个elseif写成else,结果发生错误。比如针对num为1,执行xxx;num为2,执行xxx;num为3或以上,执行xxx。这三个条件是互斥的。应该写成这样:if(num==1){}elseif(num==2){}elseif(num==3){}而不是下面这样:if(num==1){}......
  • 云课五分钟-07安装Opera失败-版本不匹配
    前篇:云课五分钟-06一段代码调试debug-AI与人工其中已经遇到了一些问题,在和文心一言交互过程中,由于提问不合适,得不到所期望的结果。那么这一节本可以避免,但是为了展示失败,需要将过程录制。 视频:云课五分钟-07安装Opera失败-版本不匹配文本:如果在一开始就询问:对于安装Opera浏览器......
  • Spring MVC 的路径匹配策略
    spring.mvc.pathmatch.matching-strategy=ant_path_matcher是一个配置项,用于设置SpringMVC的路径匹配策略。在这个例子中,它设置为使用AntPathMatcher(Ant风格的路径匹配器)。AntPathMatcher是一种基于Ant构建工具的路径匹配算法,它可以支持更灵活的路径模式匹配。通过将......
  • 刷题 二分
    2023.12.6cf1902B二分一般来讲我们会在以下情况用到二分:求单调函数的零点求最小值的最大,或最大值的最小很难直接算出答案,但是很好判定答案合不合法二分答案和二分查找差不多,就是check函数内是贪心dp之类的东西当用二分控制精度时,以r-l>eps为循环条件,mid选r和l都行,一般需......
  • Nginx篇之路由匹配规则以及配置url转发
      alias与root的区别root  实际访问文件路径会拼接URL中的路径alias  实际访问文件路径不会拼接URL中的路径示例如下:location^~/sta/{alias/usr/local/nginx/html/static/;}请求:http://test.com/sta/sta1.html实际访问:/usr/local/nginx/html/......
  • 带通配符的字符串匹配
     http://ica.openjudge.cn/function1/3/   constintN=1004;intn,m,f[N][N];chara[N],b[N];signedmain(){ inti,j; cin>>a+1>>b+1; n=strlen(a+1);m=strlen(b+1); for(i=1;i<=n;i++) if(a[i]=='*')f[i][0]=1; ......
  • Note - 整体二分
    其实是做题做不动了然后也不想卷whk于是跑来写这个。正式完工估计要咕咕咕了。多组询问,对于单组询问可以二分,但是每组暴力二分又会T,而且又可以离线,修改可以根据\(mid\)分到某一边,修改对询问的贡献有结合律、交换律时,可以考虑整体二分。即定义函数\(solve(l,r,pt)\)表......
  • Django和sqlite3版本不匹配解决 Django-django.core.exceptions.ImproperlyConfigured
    1.修改django源文件配置2升级sqlite下载sqlite3wgethttps://www.sqlite.org/2019/sqlite-autoconf-3270200.tar.gz 解压并安装sqlite3tar-zxvfsqlite-autoconf-3270200.tar.gzcdsqlite-autoconf-3270200./configure--prefix=/usr/localmake&&makeinstall......
  • OpenCV4.1.0与CUDAcuda_10.1.105联合进行图像特征点提取和特征匹配时,运行程序时错误提
    问题描述:OpenCV4.1.0与CUDAcuda_10.1.105联合进行图像特征点提取和特征匹配时,运行程序时错误提示:无法定位程序输入点?createBFMatchercv@DescriptorMatcher@cuda@cv......于动态链接库......,如下图所示:解决办法:如果include、lib和dll的路径都配置正确的话,可以尝试将编译好的带......
  • KMP字符串匹配算法 整理
    KMP整理题面视频详解KMP的作用KMP算法的主要作用是求出一个字符串(模式串)是否为另一个字符串(主串)的子串,并同时求出它出现的位置,也即字符串匹配问题。算法解析暴力先说暴力算法:从头开始枚举模式串位置的起点,然后遍历从起点往后\(m\)个字符,检查它是否与模式串完全相同......