首页 > 其他分享 >二分图匹配 - 学习心得

二分图匹配 - 学习心得

时间:2023-10-08 17:23:19浏览次数:29  
标签:二分 匹配 int scanf d% 学习心得 vis return match

就是跑匈牙利算法就行了,难点完全在于建图。

模板水题

Link

#include <bits/stdc++.h>
const int N=510;
int n,m,e;
int G[N][N],match[N];
std::bitset<N> vis;

namespace BlackWhiteGraph{
	inline void Init(void){
		scanf("%d%d",&n,&m);
		int a,t;
		for(register int i=1;i<=n;++i){
			scanf("%d",&t);
			while(t--)
				scanf("%d",&a),
				G[i][a]=1;
		}
	}
	bool dfs(int u){
		for(register int i=1;i<=m;++i){
			if(!vis[i]&&G[u][i]){
				vis[i]=true;
				if(!match[i]||dfs(match[i])){
					match[i]=u;
					return true;
				}
			}
		}
		return false;
	}
	int ans=0;
	void Match(void){
		for(register int i=1;i<=n;++i){
			vis.reset();
			if(dfs(i))++ans;
		}
	}
	void output(void){
		printf("%d\n",ans);
		exit(0);
	}
}

using namespace BlackWhiteGraph;
int main(){
	Init();
	Match();
	output();
}

直接无脑套板子然后无脑匈牙利就 \(AC\) 了。

#include <bits/stdc++.h>
#define add push_back
using namespace std;
const int N=10100;
int n,m;
vector<int> G[N];
int match[N],use[N];
bitset<N> vis;
bool dfs(int u){
	for(int v : G[u]){
		if(!vis[v]){
			vis[v]=true;
			if(!match[v] || dfs(match[v])){
				use[u]=v,match[v]=u;
				return true; 
			}	
		}
	}
	return false;
}
int main(){
	int ans=0;
	scanf("%d%d",&m,&n);
	int a,b;
	scanf("%d%d",&a,&b);
	while(a!=-1&&b!=-1){
		G[a].add(b);
		scanf("%d%d",&a,&b);
	}
	for(register int i=1;i<=n;++i){
		vis.reset();
		ans+=dfs(i);
	}
	printf("%d\n",ans);
	for(register int i=1;i<=n;++i){
		if(use[i])
			printf("%d %d\n",i,use[i]);
	}
	exit(0);
}

相比于上一道题这道题要记录路径,因为匈牙利模板自带存储路径,直接输出就行了,为什么这个东西也能进\(24\)题

稍带思维的省选题

四川省选 \(Day2\ T3\),但是水得很,直接把两个属性和物品绑在一起然后一步一步跑匈牙利就 \(AC\).

但是这道题还是有一些细节什么的,要匈牙利比较熟悉原理才能 \(AC\).

#include "bits/stdc++.h"
#define ll long long
#define add push_back
using namespace std;
const int N=1e6+10;
int n,m,col;
int vis[N],match[N];
vector<int> G[N];
bool dfs(int u){
	for(int v:G[u])
		if(vis[v]!=col){
			vis[v]=col;
			if(!match[v] || dfs(match[v])){
				match[v]=u;
				return true;
			}
		}
	return false;
}
int main(){
	scanf("%d",&n);
	int mx=-1;
	for(register int i=1;i<=n;++i){
		int u,v;
		scanf("%d%d",&u,&v);
		G[u].add(i);
		G[v].add(i);
	}
	for(register int i=1;i<N;++i){
		++col;if(!dfs(i)){
			printf("%d\n",col-1);
			break;
		}
	}
	
	return 0;
}

P2319 [HNOI2006] 超级英雄

上一题输出路径 \(AC\)

很难很难的省选题

鸽。

标签:二分,匹配,int,scanf,d%,学习心得,vis,return,match
From: https://www.cnblogs.com/qxblog/p/Black_White_Graph_note1.html

相关文章

  • 疑似std::regex_search正则匹配,导致堆栈错误
    一个很奇怪的问题,当我_beginthreadex/CreateThread创建线程,使用std::regex_search匹配时,程序会崩溃,堆栈如下:ntdll.dll!RtlReportCriticalFailure()未知ntdll.dll!RtlpHeapHandleError()未知ntdll.dll!RtlpHpHeapHandleError()未知n......
  • 动态规划——带权二分优化DP 学习笔记
    动态规划——带权二分优化DP学习笔记引入带权二分其实并不一定用于优化DP,也可能用于优化贪心等最优化的算法。带权二分也叫WQS二分,最初由王钦石在他的2012年国家集训队论文中提出。定义使用情况要解决一个最优化问题(求最大/最小值)有一个限制,一般是某个参数要求一......
  • springAMQP--DirectExchange(在监听方法上用注解声明交换机队列和key,发送消息时会带一
         ......
  • MYSQL中 find_in_set() 函数用法详解(匹配部门id或父id为100的数据)
    https://blog.csdn.net/carefree31441/article/details/119563685   ......
  • 二分
    #include<bits/stdc++.h>usingnamespacestd;booljudge(intx){}intmain(){intl,r;//000000000111111111while(l<r){intmid=l+r>>1;if(judge(mid))r=mid;elsel=mid+1;}//11......
  • 【洛谷 P1739】表达式括号匹配 题解(栈)
    表达式括号匹配题目描述假设一个表达式有英文字母(小写)、运算符(+、-、*、/)和左右小(圆)括号构成,以@作为表达式的结束符。请编写一个程序检查表达式中的左右圆括号是否匹配,若匹配,则输出YES;否则输出NO。表达式长度小于,左圆括号少于个。输入格式一行:表达式。输出格式一行:YES或NO......
  • 【二分图】CF1139E Maximize Mex 题解
    CF1139E翻译中有一句话:校长将会从每个社团中各选出一个人。就是一些人被分为一组,从每组中选一些人出来。这就很容易想到通过二分图的匹配。\(\text{mex}\)运算有一个显而易见的贪心:枚举每个值能否被匹配,第一个找不到的值就是答案。由于\(\text{mex}\)运算的值域与\(n\)......
  • KMP 字符匹配
    忘了具体什么时候写的,应该是2023.8初这算是个算法复习,因为我太菜了以前学的都不会了。KMP字符匹配有一说一这个我讲不来,大概意思就列这好了:Knuth(D.E.Knuth)&Morris(J.H.Morris)&Pratt(V.R.Pratt)提出的字符串匹配算法,简称KMP。KMP算法应该是最基础的字符串匹配算法了,......
  • PostgreSQL 的模式匹配与正则表达式
    一、PostgreSQL实现模式匹配的方法LIKESIMILARTOPOSIX风格的正则表达式模式匹配函数substring二、LIKE操作符只有在匹配整个字符串时返回真符号描述%任意0个或任意个字符_任意一个字符\%%\__postgres=#select*fromtest_zhengze;id|......
  • 【二分】P7795 [COCI2014-2015#7] PROSJEK 题解
    P7795典。显然\(\mathcal{O}(n^2)\)的时间复杂度无法通过。使子段平均值最大,考虑二分。可以二分平均值\(mid\),然后判断是否有满足条件的子段.时间复杂度:\(\mathcal{O}(\dfrac{n\log\max\{a_i\}}{\text{eps}})\),其中\(\text{eps}\)为设置的精度,\(\max\{a_i\}\leq10......