您的位置:首页 > 其它

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

2007-09-17 04:57 453 查看
看书看了好久,看不懂。
上网找代码研究,还是不懂。
突然瞄到书上的插图,顿悟,哈哈^_^
这里的代码修改了一些,贴上来。。

// 二分图的最大匹配(匈牙利算法)
#include <cstdio>
#include <memory.h>
using namespace std;

const int XV = 100;
const int YV = 300;
int xv, yv; // X , Y 点集的大小
int adj [XV] [YV]; // adj [i] [j] != 0 表示 xi 与 yj 邻接
bool sy [YV]; // 每轮中对于被搜过的点 yi , sy [i] = 1
int xm [XV]; // xm [i] 保存 xi 匹配的 Y 点
int ym [YV]; // ym [i] 保存 yi 匹配的 X 点

int path (int u)
{
//对于 X 中的点 u ,返回能否找到增广路(也即能否增大匹配数,递归,时间复杂度 O (xv * yv))
for (int v = 0; v < yv; v ++)
{
if (adj [u] [v] && !sy [v])
{
sy [v] = true;
if (ym [v] == -1 || path (ym [v]) == 1)
{
xm [u] = v;
ym [v] = u;
return 1;
}
}
}
return 0;
}

int maxmatch ()
{
int cnt = 0; // 匹配数
memset (xm, -1, sizeof (xm)); // xm [i] == -1 表示 xi 尚未匹配
memset (ym, -1, sizeof (ym));
for (int u = 0; u < xv; u ++)
{
if (xm [u] == -1)
{
memset (sy, 0, sizeof (sy));
cnt += path (u);
}
}
return cnt;
}

int main()
{
scanf ("%d%d", &xv, &yv); // 输入 X , Y 点集的大小

// 输入邻接矩阵,两种方式

int edge;
scanf ("%d", &edge); // 输入边数
memset (adj, 0, sizeof (adj));
for (int i = 0; i < edge; i ++)
{
int u, v;
scanf ("%d%d", &u, &v); // 输入关联的两点
adj [u] [v] = 1;
}
/*
6 6 10
0 0
0 2
1 3
1 5
2 1
2 3
3 4
4 4
4 5
5 5
6 6
*/
/*************************************************
for (int i = 0; i < xv; i ++)
{
for (int j = 0; j < yv; j ++)
{
scanf ("%d", &adj [i] [j]);
}
}
*/
/*
1 0 1 0 0 0
0 0 0 1 0 1
0 1 0 0 0 1
0 0 0 0 1 0
0 0 0 0 1 1
0 0 0 0 0 1
**************************************************/

int cnt = maxmatch (); // 匹配

// 打印
printf ("The maxmatch count is %d ", cnt);
for (int i = 0; i < xv; i ++)
{
printf ("%d ", xm [i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: