参考两篇比较好的博客

http://www.renfei.org/blog/bipartite-matching.html

http://blog.csdn.net/thundermrbird/article/details/52231639###;

最大匹配数为n     2*n个不同的点    n条不同的边

匈牙利算法

从未匹配的的点出发寻找   非匹配边大于匹配边的交替路(增广路)匹配边与非匹配边交换

匈牙利算法模板(DFS,邻接矩阵版) 时间复杂度O(V*E)

 #include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <string>
#include <queue>
#include <map>
#include <vector>
using namespace std;
const int maxn = ;
const int maxm = 1e4+;
const int inf = 0x3f3f3f3f;
const double epx = 1e-;
typedef long long ll;
int n,m,k;
int visit[maxn];
int match[maxn];
int a[maxn][maxn];
bool found(int x)
{
for(int i=;i<=m;i++) //从右边的集合中找能与x进行匹配的点
{
if(a[x][i]==&&visit[i]==) //x与i有联系且i没被查找过
{
visit[i]=;
if(match[i]==||found(match[i])) //第i个点还没有匹配 如果匹配了就看 与它匹配的那个点 能不能换个点完成匹配 把i空出来 如果可以i与x匹配
{
match[i]=x;
return true;
}
}
}
return false;
}
int main()
{
while(scanf("%d",&k)!=EOF&&k) //k条边
{
scanf("%d%d",&n,&m); //左右两个集合的数量
memset(a,,sizeof(a));
for(int i=;i<=k;i++)
{
int x,y;
scanf("%d %d",&x,&y);
a[x][y]=; //有联系的点标记为1
}
memset(match,,sizeof(match));
int ans=;
for(int i=;i<=n;i++) //依次对左边集合中点进行匹配
{
memset(visit,,sizeof(visit)); //清空访问标记数组
if(found(i))             //满足条件匹配数+1
ans++;
}
printf("%d\n",ans);
}
}

Hopcroft-Karp 算法

复杂度 O(sqrt(n)*E)

邻接表存图,vector 实现 ,vector 先初始化,然后加入边 , uN 为左端的顶点数,使用前赋值 (点编号 0 开始)

#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
#define huan printf("\n")
#define debug(a,b) cout<<a<<" "<<b<<" "<<endl
#define ffread(a) fastIO::read(a)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int MAXN = +;
const int INF = 0x3f3f3f3f;
vector<int>G[MAXN];
int uN;
int Mx[MAXN],My[MAXN];
int dx[MAXN],dy[MAXN];
int dis;
bool used[MAXN];
void init(int n)
{
uN=n;
for(int i=; i<n; i++)
G[i].clear();
}
bool SearchP()
{
queue<int>Q;
dis = INF;
memset(dx,-,sizeof(dx));
memset(dy,-,sizeof(dy));
for(int i = ; i < uN; i++)
if(Mx[i]==-)
{
Q.push(i);
dx[i] = ; }
while(!Q.empty())
{
int u = Q.front();
Q.pop();
if(dx[u] > dis)
break;
int sz = G[u].size();
for(int i = ; i < sz; i++)
{
int v = G[u][i];
if(dy[v]==-)
{
dy[v] = dx[u] + ;
if(My[v] == -)
dis = dy[v];
else
{
dx[My[v]] = dy[v] + ;
Q.push(My[v]);
}
}
}
}
return dis != INF;
}
bool DFS(int u)
{
int sz = G[u].size();
for(int i = ; i < sz; i++)
{
int v = G[u][i];
if(!used[v] && dy[v] == dx[u] + )
{
used[v] = true;
if(My[v] != - && dy[v] == dis)
continue;
if(My[v] == - || DFS(My[v]))
{
My[v] = u;
Mx[u] = v;
return true;
}
}
}
return false;
}
int MaxMatch()
{
int res = ;
memset(Mx,-,sizeof(Mx));
memset(My,-,sizeof(My));
while(SearchP())
{
memset(used,false,sizeof(used));
for(int i = ; i < uN; i++)
if(Mx[i] == - && DFS(i))
res++;
}
return res;
}
int main()
{
int n,m,k;
while(scanf("%d",&k)&&k)
{
scanf("%d%d",&m,&n);
init(m);
for(int i=; i<k; i++)
{
int x,y;
scanf("%d%d",&x,&y);
G[x-].pb(y-);
}
printf("%d\n",MaxMatch());
}
}

无权二分图最大匹配 HDU2063 匈牙利算法 || Hopcroft-Karp的更多相关文章

  1. "《算法导论》之‘图’":不带权二分图最大匹配(匈牙利算法)

    博文“二分图的最大匹配.完美匹配和匈牙利算法”对二分图相关的几个概念讲的特别形象,特别容易理解.本文介绍部分主要摘自此博文. 还有其他可参考博文: 趣写算法系列之--匈牙利算法 用于二分图匹配的匈牙利 ...

  2. 二分图最大匹配(匈牙利算法)简介& Example hdu 1150 Machine Schedule

    二分图匹配(匈牙利算法) 1.一个二分图中的最大匹配数等于这个图中的最小点覆盖数 König定理是一个二分图中很重要的定理,它的意思是,一个二分图中的最大匹配数等于这个图中的最小点覆盖数.如果你还不知 ...

  3. 二分图最大匹配:匈牙利算法的python实现

    二分图匹配是很常见的算法问题,一般用匈牙利算法解决二分图最大匹配问题,但是目前网上绝大多数都是C/C++实现版本,没有python版本,于是就用python实现了一下深度优先的匈牙利算法,本文使用的是 ...

  4. 51nod 2006 飞行员配对(二分图最大匹配) 裸匈牙利算法 求二分图最大匹配题

    题目: 题目已经说了是最大二分匹配题, 查了一下最大二分匹配题有两种解法, 匈牙利算法和网络流. 看了一下觉得匈牙利算法更好理解, 然后我照着小红书模板打了一遍就过了. 匈牙利算法:先试着把没用过的左 ...

  5. 【模板】二分图最大匹配(匈牙利算法)/洛谷P3386

    题目链接 https://www.luogu.com.cn/problem/P3386 题目大意 给定一个二分图,其左部点的个数为 \(n\),右部点的个数为 \(m\),边数为 \(e\),求其最大 ...

  6. 【hihocoder 1122】二分图二•二分图最大匹配之匈牙利算法

    [Link]:https://hihocoder.com/problemset/problem/1122 [Description] [Solution] 二分图匹配,匈牙利算法模板题; 这里我先把染 ...

  7. [hihoCoder] #1122 : 二分图二•二分图最大匹配之匈牙利算法

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上一回我们已经将所有有问题的相亲情况表剔除了,那么接下来要做的就是安排相亲了.因为过年时间并不是很长,所以姑姑希望能够尽可 ...

  8. hihoCoder#1122(二分图最大匹配之匈牙利算法)

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上一回我们已经将所有有问题的相亲情况表剔除了,那么接下来要做的就是安排相亲了.因为过年时间并不是很长,所以姑姑希望能够尽可 ...

  9. hihocoder #1122 二分图二•二分图最大匹配之匈牙利算法(*【模板】应用 )

    梳理整个算法: 1. 依次枚举每一个点i: 2. 若点i尚未匹配,则以此点为起点查询一次交错路径. 最后即可得到最大匹配数. 在这个基础上仍然有两个可以优化的地方: 1.对于点的枚举:当我们枚举了所有 ...

随机推荐

  1. MVC C# 直接导出txt文件

    用asp.net根据数据内容自动生成一个txt文本文件并提供用户下载,此方法文件不保存在服务器上,直接提供给用户下载,到网上搜了一下,都是用的Response.BinaryWrite(),用了几下,发 ...

  2. Spring注解驱动开发之扩展原理

    前言:现今SpringBoot.SpringCloud技术非常火热,作为Spring之上的框架,他们大量使用到了Spring的一些底层注解.原理,比如@Conditional.@Import.@Ena ...

  3. sqlServer备份和还原语句

    数据库备份语句和还原语句: --完整备份 Backup Database xxx To disk=’G:\Backup\xxx.bak’ --查看物理路径 restore filelistonly f ...

  4. poj2886 Who Gets the Most Candies?

    思路: 先打反素数表,即可确定因子最多的那个数.然后模拟踢人的过程确定对应的人名.模拟的过程使用线段树优化加速. 实现: #include <cstdio> #include <cs ...

  5. ASP.NET中调用事务处理的方法

    /// <summary> /// 事务处理 /// </summary> /// <param name="strSql"></para ...

  6. MVC学习(一)

    http://www.cnblogs.com/QLeelulu/archive/2008/09/30/1302462.html

  7. 微信小程序中的图形验证码

    可以在utils中新建一个mcaptcha.js 代码如下: module.exports = class Mcaptcha { constructor(options) { this.options ...

  8. 初学者对C++的切身感受

    上周和一同学聊起了当前一些比较流行且运用广范的编程语言,苹果的IOS比起其它语言 来说更加言简意赅,简单明了,并且他现在也打算一直弄IOS.我之前一直是用C语言和 GNU ARM汇编语言,因为这两种语 ...

  9. CE工具里自带的学习工具--第三关

    图解: 重复第5,6,7,8,9步,最终得到:

  10. 03C#数据类型

    C#数据类型 值类型和引用类型区别 在C#语言中,值类型变量存储的是指定数据类型的数据,值类型变量的值(或实例)存储在栈(Stack)中,赋值语句是传递变量的值.引用类型(例如类就是引用类型)的实例, ...