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

从左边开始,看每个点能不能匹配到右边的一个点

如果连到的点没被匹配( \(p[j] == 0\) )匹配成功

如果连到的点被匹配了,看这个点原来匹配的左面的点,能不能匹配别的右面的点( \(match(p[j])\) )

int M, N;            //M, N分别表示左、右侧集合的元素数量
int Map[MAXM][MAXN]; //邻接矩阵存图
int p[MAXN];         //记录当前右侧元素所对应的左侧元素
bool vis[MAXN];      //记录右侧元素是否已被访问过
bool match(int i)
{
    for (int j = 1; j <= N; ++j)
        if (Map[i][j] && !vis[j]) //有边且未访问
        {
            vis[j] = true;                //记录状态为访问过
            if (p[j] == 0 || match(p[j])) //如果暂无匹配,或者原来匹配的左侧元素可以找到新的匹配
            {
                p[j] = i;    //当前左侧元素成为当前右侧元素的新匹配
                return true; //返回匹配成功
            }
        }
    return false; //循环结束,仍未找到匹配,返回匹配失败
}
int Hungarian()
{
    int cnt = 0;
    for (int i = 1; i <= M; ++i)
    {
        memset(vis, 0, sizeof(vis)); //重置vis数组
        if(match(i)) cnt++;
    }
    return cnt;
}

posted @ 2023-02-04 18:06  f2021yjm  阅读(22)  评论(0编辑  收藏  举报