nyoj-239 月老的难题 (二分图匹配—匈牙利算法 && 网络流—Dinic算法)

[HQChart教程] 去掉“仅学习使用”文字提示的小技巧 最近用 HQChart 做图表时,发现左下角有“仅学习使用”的字样。这种水印虽然是默认的,但如果要展示给客户,可能会显得不够专业。还好,这个问题很好解决,只需要简单修改一下配置。 阅读详情

月老的难题

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 4
描述

月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘。

现在,由于一些原因,部分男孩与女孩可能结成幸福的一家,部分可能不会结成幸福的家庭。

现在已知哪些男孩与哪些女孩如果结婚的话,可以结成幸福的家庭,月老准备促成尽可能多的幸福家庭,请你帮他找出最多可能促成的幸福家庭数量吧。

假设男孩们分别编号为1~n,女孩们也分别编号为1~n。

输入
第一行是一个整数T,表示测试数据的组数(1<=T<=400)
每组测试数据的第一行有两个整数n,K,其中男孩的人数与女孩的人数都是n。(n<=500,K<=10 000)
随后的K行,每行有两个整数i,j表示第i个男孩与第j个女孩有可能结成幸福的家庭。(1<=i,j<=n)
输出
对每组测试数据,输出最多可能促成的幸福家庭数量
样例输入
1
3 4
1 1
1 3
2 2
3 2
样例输出
2


思路: 

       此题是经典的二分图匹配模板题,学习网络流后发现也可解(只需加一个超级源点和超级汇点,就变成了网路流的模板题)。刚好初学这两种算法,便将此题作为模板题整理下来;二分图匈牙利算法与网络流的Dinic算法耗时相当,但网络流(使用邻接表建图)的空间消耗较大;

       二分图匹配—匈牙利算法, 资料:http://kukumayas.iteye.com/blog/1075610 

       http://blog.youkuaiyun.com/niushuai666/article/details/7023101 


匈牙利算法代码:

#include <stdio.h>
#include <string.h>
#include <vector>
#define N 520

using namespace std;

int P_Num;					// 人数 
vector<int>Boy[N];			// 临界表,保存匹配信息 
bool use[N];				// 标记数组 
int form[N];				// 父节点(i号女生对应的男生编号) 

bool Match(int cur){										// 匹配函数 
	for(int i = 0; i < Boy[cur].size(); i ++){				// 遍历所有能与cur男生匹配的女生 
		if(!use[ Boy[cur].at(i) ]){							// 判断该女生结点是否被判断过,没有进入 
			use[ Boy[cur].at(i) ] = 1;						// 标记该女生已经判断 
			if(form[ Boy[cur].at(i) ] == -1 || Match(form[ Boy[cur].at(i) ])){		// 如果该女生未被匹配,或者之前匹配该女生的男生可以匹配其它女生 
				form[ Boy[cur].at(i) ] = cur;				// 则将该女生匹配给cur男生
				return 1;									// 成功匹配返回1 
			}
		}
	}
	
	return 0;
}

int Hungary(){									// 匈牙利算法 
	int count = 0;								// 计数器 
	memset(form, -1, sizeof(form));				// form保存女生对应的男生的编号,初始化为-1 
	
	for(int i = 1; i <= P_Num; i ++){			// 遍历每个男生结点,与女生深搜匹配 
		memset(use, 0, sizeof(use));			// 匹配前先将标记数组清零,起作用是防止重复搜索某结点 
		count += Match(i);
	}
	
	return count;
}

int main() 
{
	int loop, G_Num;
	scanf("%d", &loop);
	while(loop --){
		int start, end;
		scanf("%d%d", &P_Num, &G_Num);
		
		for(int i = 1; i <= P_Num; i ++){			// 多组数据初始化,清空数组 
			Boy[i].clear();
		}
		
		for(int i = 0; i < G_Num; i ++){
			scanf("%d%d", &start, &end);
			Boy[start].push_back(end);
		}
		
		int ans = Hungary();
		
		printf("%d\n", ans);
	}
	
	return 0;
}


网络流代码:

#include <stdio.h>
#include <string.h>
#include <queue>
#define INF 0x7fffffff
#define N 1020

using namespace std;

struct Node{
	int to;
	int weight;
	int next;
};

Node edge[N * 100];
int head[N];
int level[N];
int edge_n;

int min(int a, int b)
{
	return a < b ? a : b;
}

void AddEdge(int start, int end, int weight)
{
	edge[edge_n].to = end;
	edge[edge_n].weight = weight;
	edge[edge_n].next = head[start];
	head[start] = edge_n ++;

	edge[edge_n].to = start;
	edge[edge_n].weight = 0;
	edge[edge_n].next = head[end];
	head[end] = edge_n ++;
}

bool bfs(int start, int end)
{
	memset(level, 0, sizeof(level));
	queue<int>q;

	q.push(start);
	level[start] = 1;

	int cur;
	while(!q.empty()){
		cur = q.front();
		q.pop();

		for(int i = head[cur]; i != -1; i = edge[i].next){
			int v = edge[i].to;
			int w = edge[i].weight;
			if(w > 0 && !level[v]){
				level[v] = level[cur] + 1;
				if(v == end){
					return 1;
				}
				q.push(v);
			}
		}
	}

	return 0;
}

int dfs(int cur, int end, int cp)
{
	if(cur == end){
		return cp;
	}

	int t, tmp = cp;
	for(int i = head[cur]; i != -1 && tmp; i = edge[i].next){
		int v = edge[i].to;
		int w = edge[i].weight;
		if(level[v] == level[cur] + 1 && w > 0){
			t = dfs(v, end, min(tmp, w));
			edge[i].weight -= t;
			edge[i ^ 1].weight += t;
			tmp -= t;
		}
	}

	return cp - tmp;
}

int Dinic(int start, int end)
{
	int ans = 0, min_w;
	while( bfs(start, end) ){
		while( min_w = dfs(start, end, INF) ){
			ans += min_w;
		}
	}

	return ans;
}

int main()
{
	int loop, ans;
	int p_num, ct;			// 男女人数,关系数目
	int boy_i, girl_i;
	scanf("%d", &loop);
	while(loop --){
		edge_n = 0;
		memset(head, -1, sizeof(head));

		scanf("%d%d", &p_num, &ct);
		while(ct --){						// 建图
			scanf("%d%d", &boy_i, &girl_i);
			AddEdge(boy_i, girl_i + p_num, 1);
		}

		int src = 0, des = p_num * 2 + 1;	// 超级源点,超级汇点
		for(int i = 1; i <= p_num; i ++){
			AddEdge(src, i, 1);
			AddEdge(i + p_num, des, 1);
		}
		ans = Dinic(src, des);
		printf("%d\n", ans);
	}

	return 0;
}


HarmonyOS应用开发者基础认证 B. 自定义组件:可复用的 UI 单元,可组合其它组件。D. 内置组件:ArkTS中默认内置的基本组件和布局组件,开发者可以直接调用,如Column、Text、Divider、Button等。E. 属性方法:用于组件属性的配置,统一通过属性方法进行设置,如fontSize()、width()、height()、color() 等。在Column和Row容器组件中,justifyContent用于设置子组件在主轴方向上的对齐格式,alignItems用于设置子组件在交叉轴方向上的对齐格式。 阅读详情

相关推荐

手把手教你用STM32的SPI驱动MCP2517FD实现CAN FD通信(附完整代码)

本文详细介绍了如何使用STM32通过SPI驱动MCP2517FD实现CAN FD通信,涵盖硬件连接、SPI驱动编写、寄存器配置及数据收发实战。提供完整代码示例和常见问题排查指南,帮助开发者快速构建高可靠性的CAN FD通信系统,适用于汽车电子和工业控制等领域。

weixin_30607029的博客 676

二分图最大匹配(匈牙利算法&Dinic算法)

二分图最大匹配: 给出一个二分图,左边有若干个节点,右边有若干个节点,左边的节点想到匹配右边的节点,每个左边的节点每个都有若干个可以选择的对象,每个左边节点只能选择一个右边节点,每个右边节点也只能被选择一次。现在问你左边的节点能完成匹配的做多能有几个? 通俗一点就是,有一群人,有一堆奖品,每个人都有自己心仪的奖品,每种奖品只有一份,问你最多能有多少能拿到自己心仪的奖品(每个人只能拿一份,而且每个人可能有多重心仪的奖品)? 匈牙利算法: 匈牙利算法的做法就是,先让每个左边节点去匹配,如果存在没有被匹配到的右边

qq_36102055的博客 1376

DeepSeek-V4-Pro 正式版突袭上线:Agent 能力暴涨,DeepSWE 直接干翻 Claude Opus 4.8

8 月 12 日深夜,DeepSeek 悄悄在 API 文档里上架了一个新版本号——DeepSeek-V4-Pro-0813。第二天(13 日),这个版本被确认为 V4 Pro 正式版。没有发布会,没有预热,只改了版本号,就把整个 AI 圈的注意力又抢了过去。

2601_96613114的博客 840

最大流——Dinic

    上回介绍了EK算法,这次来学一个效率更高的算法。我们在做EK算法的时候,每次bfs最多遍历了整个残量网络,但是只找到了一条增广路。所以有可以优化的地方。Dinic算法基于分层图,我们先bfs找到一个合法的有向无环图(图中所有边都有残流,图严格按照拓扑序),然后在这张分层图上通过深度优先搜索找到若干条合法不冲突的增广路,累加到maxflow里。并且可以在dfs里添加剪枝:如果当前点以后找不到...

Destiny 955

爬取百度图片

最开始,我们想要爬取图片,首先需要打开百度图库,然后在搜索栏中输入自己想要的图片(比如说壁纸)。接着右键检查,点击网络:起初可能没有名称信息,刷新界面就可以了。打开信息,查看标头内容可以看到请求URL为:复制这串URL,然后在浏览器中打开这个就是我们搜索的壁纸图片的网页内容。怎么找到图片的URL呢?在上述内容中,找到data,可以发现里面每隔一个aiEditData,下面代码的形式是一样的,就相当于一张图片。

weixin_54143563的博客 1943

薛定谔虚拟筛选实战:如何用PDB文件快速构建受体格点(避坑指南)

本文提供了薛定谔虚拟筛选实战指南,聚焦于如何从PDB文件快速、精准地构建受体格点。文章详细解析了可变残基的理性处理策略、基于配体尺寸的盒子量化设置方法,并分享了高级约束与排除体积的实战技巧,旨在帮助用户避开常见陷阱,提升虚拟筛选的成功率与效率。

weixin_28419039的博客 254

网络流dinic算法复杂度

Dinic算法的时间复杂度的理论上界是O(N2*M)(N是结点数,M是边数),但实际上Dinic算法比这个理论上界好得多。如果所有边容量均为1,那么时间复杂度是O(min(N0.67,M0.5) * M) ;对于二分图最大匹配这样的特殊图,时间复杂度是O(N0.5 * M)。 ...

凝望的博客 7153

Polyworks脚本开发实战指南:高效生成数据彩图与报告的关键指令解析

本文深入解析了Polyworks脚本开发中生成数据彩图与自动化报告的核心指令。通过实战案例,详细介绍了REFERENCE_SURFACE、THICKNESS和CLEARANCE等关键彩图生成指令的正确用法与常见避坑点,并阐述了如何利用REPORT_ITEM命令实现从截图、表格生成到智能排版的全流程自动化,旨在帮助三维检测与质量控制工程师大幅提升工作效率与报告标准化水平。

weixin_29209825的博客 556

二分图最大匹配(匈牙利算法,Dinic网络流算法)

二分图最大匹配问题: 有两个集合A,B,两个集合间有多条边连接集合中的点,且单个集合中的点各不相连,求两集合的点能两两配对的最大匹配数. (参考:)二分图最大匹配——匈牙利算法 匈牙利算法: A集合记录各点与B集合相连的点,B集合记录某点与A集合中匹配的点.遍历A集合中的每一点,寻找最大匹配. 每一点顺序选取B集合中没被匹配过的点,若有,则将B集合中的点与该点匹配,跳转至下一个点. 若没有未匹配的点,顺序遍历所有有连接的点,看该点已匹配的点能否选择其他点去匹配,这是一个递归过程. 如:A1与B1,B2连;A

Khasehemwy的博客 2655

图注意力网络(GAT)原理与代码实战案例讲解

1. 背景介绍 图注意力网络(Graph Attention Network,简称GAT)是一种基于图神经网络(Graph Neural Networks,简称GNN)的深度学习方法。它能够处理具有复杂关系的节点数据,并在多个领域取得了显著的效果,如社交网络分析、推荐系统等。 2. 核心概念与联系

AI架构师小马 2715

验证码破解2.0:Python+CV大模型搞定滑块/点选验证

核心创新:基于YOLOv8+SAM CV大模型的端到端验证码破解方案,无需人工设计特征,适配多种验证码类型;核心价值高成功率:滑块验证≥95%,点选验证≥90%,远超传统CV方案;低延迟:单验证码破解≤2秒,满足高并发采集需求;行为模拟:生成符合人类操作的轨迹,绕过行为检测;易扩展:统一架构支持新增验证码类型,仅需少量标注数据微调;技术要点采用YOLOv8实现快速目标检测,SAM实现像素级分割;生成物理规律的人类轨迹,模拟真实操作行为;

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1261

网络流(二)最大流之二分图匹配

网络流(二)最大流之二分图匹配

cjx2774952383的博客 2014

小红书直播弹幕采集

本文主要介绍小红书直播间弹幕的采集,便于进行直播数据监控与直播数据进行分析。

tdl320721的博客 2542

图论进阶——二分图匹配(匈牙利+网络流算法)

前置知识 二分图染色 注意事项 首先,这张图需要是一个二分图 二分图匹配定义 在一个二分图内找出一些边,使得任何一个图中的点都被至多一条边连接,这些边的集合叫做一个二分图匹配。 如果存在一种二分图匹配方案,使得选出的边的数量最多,那么这就叫做二分图的最大匹配。 如果该二分图的最大匹配方案中,所有的顶点均被一条边所连接,那么这个方案就叫做二分图的一个完美匹配。 二分图匹配算法 1.1.1.匈牙利算法...

wljoi的博客 1939

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

23 HK 最快的最大匹配算法;一个比匈牙利匹配算法快的算法;o(sqrt(n)*E);

F - Rain on your Parade You’re giving a party in the garden of your villa by the sea. The party is a huge success, and everyone is here. It’s a warm, sunny evening, and a soothing wind sends fresh, s...

qq_39792342的博客 1660

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

匈牙利算法

一.介绍 匈牙利算法几乎是二分图匹配的核心算法,除了二分图多重匹配外均可使用 匈牙利算法实际上就是一种网络流的思想,其核心就是寻找增广路 二.流程 板题:hdu2063 链接:https://acm.hdu.edu.cn/showproblem.php?pid=2063 给定的关系,先进行匹配,如果遇到没法匹配的情况,那么给之前匹配的进行重新匹配,直接找到一种可行的匹配。 例如: 如果女1和男1,男2,有关系,女2和男2,男3有关系,女3和男1,男2有关系,女4和男3有关系。 先让,女1和男1匹配。 再

weixin_45681381的博客 479

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Machine Schedule-匈牙利算法/Dinic

Machine Schedule 问题来源:Hdu-1150 Problem Description As we all know, machine scheduling is a very classical problem in computer science and has been studied for a very long history. Scheduling prob

u014366015的专栏 913

P3386 【模板】二分图匹配 Ek 与 dinic

题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每行两个正整数u,v,表示u,v有一条连边 输出格式: 共一行,二分图最大匹配 输入输出样例 输入样例#1: 复制 1 1 1 1 1 输出样例#1: 复制 1 说明  n

Algorithm_Art的博客 972

飞行员配对方案(Dinic求最大二分图匹配(对匈牙利算法的优化),以及二分图的建图方式)

飞行员配对方案 二分图最大流建图方式: 1.源点S与每个外籍飞行员有向边连边,权值为1 2.每个英国本地飞行员与汇点连接有向边,权值为1 3根据题意,外籍与本地飞行员连接有向边,权值为1. 输出方式: 最后输出方案数: 当某个可行流被选了之后经过的所有正向边都会−=t-=t−=t. 最后中间外籍与本地飞行员连接关系的正向有向边如果为0,则此边为最小割集(已被选出)即最大流, 割集对应的点,就是选的方案 #include<bits/stdc++.h> using namespace std; co

qq_52093121的博客 609

codevs 1922 骑士共存问题||二分图||最大独立集||二分图匹配||Dinic与匈牙利算法的讨论||网络流

**1922 骑士共存问题** **题目描述 Description** 在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示。棋盘 上某些方格设置了障碍,骑士不得进入。对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑 士,使得它们彼此互不攻击。**输入描述 Input Description** 第一行有2 个正整数n 和m (1<=n<

远方 2557

HDU3605  Escape 二分图多重匹配 匈牙利算法&最大流Dinic算法

 Escape 2012 If this is the end of the world how to do? I do not know how. But now scientists have found that some stars, who can live, but some people do not fit to live some of the planet. Now scie...

紫芝的博客 749

二分图最大匹配【匈牙利 || Dinic最大流】

二分图最大匹配模板【匈牙利;Dinic最大流】 匈牙利算法 int n,m; vector&amp;amp;amp;amp;lt;int&amp;amp;amp;amp;gt; map[100010]; int match[100010];//保存匹配的互相点 bool vis[100010]; bool dfs(int u) { for(int j=0;j&amp;amp;amp;amp;lt;map[u].size();

niiick 1439

UVa11419 - SAM I AM(二分图/网络流【坑*方案问题)

题目链接 简介: 子弹打小怪,一发打一行(列),求最小花费的子弹数,并给出方案 分析: 曾经做过和这个有一点相似的题(我又开始考古啦) 然而这道题要简单一点, 还是把每一行,每一列看作是一个点, 如果(i,j)位置上有小怪物,那我们就连接Xi—>Yj,流量是INF 源点向横向点集(X)连边,流量为1 纵向点集(Y)向汇点连边,流量是1 为...

weixin_30257433的博客 194

二分图最大匹配——匈牙利算法,网络流初步——最大流问题+最小费用最大流+常用建图

二分图最大匹配——匈牙利算法 对不起 懒得粘 图太多 但是真的好秀 人家创作的确实好,真丶看一遍就懂了 作者:Dark_Scope 来源:优快云 原文:https://blog.youkuaiyun.com/dark_scope/article/details/8880547 写这个博客 主要还不是不喜欢书上的板子,自己理解后按照自己的理解写出最适合自己的板子多好 留个匈牙利算法的...

permi_yaxileni的博客 2706

POJ 2239 Selecting Courses(二分图匹配——匈牙利算法||网络流)解题报告

题目大意: 在大学里有许许多多的课程,现在李明需要去选择课程,他是一个爱学习的人,所以想尽可能多的选择课程。 在学校里有n个课程,每周7天,每天有12节课,一周一共有有7*12节课。某一节课在一周内会上x次,一周内的这x次内容一样,只需要去一次就可以了。同时,某个时间李明最多只能去上一门课程。问李明最多能上多少门课。 输入第一行为n,代表有n个课程。接下来n行,每行第一个数字x代表这个课程在

Light_Time 1005

【POJ - 2226】Muddy Fields(匈牙利算法 或 网络流dinic,二分图匹配,最小点覆盖,矩阵中优秀的建图方式 )

题干: Rain has pummeled the cows' field, a rectangular grid of R rows and C columns (1 &lt;= R &lt;= 50, 1 &lt;= C &lt;= 50). While good for the grass, the rain makes some patches of bare earth quite m...

xuanweiace的博客 676
上一篇: poj-1006 生理周期(中国剩余定理)
下一篇: nyoj-409 郁闷的C小加(三) (表达式求值,中缀式转前缀式,中缀式转后缀式)
tbl00c
博客等级 码龄13年 21粉丝 91原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值