匈牙利算法

月老算法

匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名。匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法。

匈牙利算法Hungarian algorithm)。匈牙利算法主要用于解决一些与二分图匹配有关的问题,

易懂博客:趣写算法系列之--匈牙利算法_DarkScope从这里开始-CSDN博客_匈牙利算法.

相关题目:

POJ - 2446   

Chessboard

有一天,罗老板画了一块尺寸为M * N的棋盘。他希望许老师能够使用1 * 2的牌来覆盖棋盘。然而,他认为这很容易,所以他增大了难度,他在棋盘上打了一些洞

许老师必须遵守以下规则:
1.任何不是洞网格都应该只被一张卡覆盖。
2. 一张卡应该正好覆盖2个相邻非洞网格。
3. 洞不可以被卡片覆盖

匈牙利算法_第1张图片


一个正确的覆盖

匈牙利算法_第2张图片


一个错误操作,有一个红色的洞被卡片覆盖了.

匈牙利算法_第3张图片


一个错误操作,有一个非洞网格没有被卡片覆盖.


你的任务是帮助许老师确定 根据上述规则 是否存在一种方案可以覆盖棋盘

Input

第一行三个整数: m, n, k (0 < m, n <= 32, 0 <= K < m * n), 表示棋盘的行数, 列数 和洞的数量. 接下来k行,每行一对数字 (x, y) , 表示第y行第x列的格子为一个洞

Output

I如果存在一种方案覆盖棋盘就输出YES,否则输出 NO。

Sample Input

4 3 2
2 1
3 3

Sample Output

YES

题意是要用多条纸带覆盖一幅图的格子,因为一条纸带只能覆盖两个相邻的格子,我们将有洞的排除掉,将好的分成奇数和偶数号格子(我这里是根据横纵坐标和的奇偶性来分)。

把奇数格子和偶数格子当成二分图的两个集合求最大匹配边即可。如果最大匹配边数乘2和剩下格子数相等,就可以全覆盖。如果剩下格子为单数必定不能全覆盖。

AC代码:

#include
#include
#include
using namespace std;
const int N=35*35;
int n,m,k;
bool vis[N][N];//判断是否为洞
int map[N][N];//
int g[N][N];//邻接矩阵(数据大时要用邻接表)
int used[N];//
int belong[N];//记录i点属于谁
int v1,v2;//v1是奇数格子的个数,v2是偶数格子的个数
int dir[4][2]={0,1,1,0,0,-1,-1,0};
bool find(int x)
{
 
	for(int i=1;i>n>>m>>k;// 
	if((n*m-k)%2!=0){  
		printf("NO\n");  
		return 0;
	}
	for(int i=0;i>x>>y;
		vis[y-1][x-1]=true;//  坑
		}	
		int sum=0;
		v1=1,v2=1;
			for(int i=0;i=0&&dx=0&&dy

 我一开始写时,是把第一个格子到最后记为1,2,,,,n*m,没有明确分成两个集合,一直wa;

然后借鉴网上的做法,将所有偶数格子记录为1,2,,,所有奇数格子记录为1,2,,,然后用偶数格子匹配奇数格子(也可用奇数格子匹配偶数格子),套匈牙利模板就过了。

你可能感兴趣的:(算法)