图论---匈牙利算法求二分图最大匹配的实现

开始编程前分析设计思路和程序的整体的框架,以及作为数学问题的性质:

程序流程图:

数学原理:

求解二分图最大匹配问题的算法,寻找一个边的子集,使得每个左部点都与右部点相连,并且没有两条边共享相同的端点。使用深度优先搜索来寻找增广路径。当找到一条增广路径时,将路径上的边加入匹配集合中,并更新匹配状态。重复这个过程直到无法找到增广路径为止。

时间复杂度分析:

时间消耗来自于DFS搜索和增广路径的寻找。对于每个左侧未匹配的点u,需要进行一次DFS搜索。在最坏情况下,DFS搜索需要遍历所有的右侧点,因此时间复杂度为O(n)。由于需要进行n次DFS搜索,所以时间复杂度为O(n^2)。

源代码:

cpp 复制代码
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

const int MAXN = 505; // 最大顶点数
int n, m, k; // n为左部点数,m为右部点数,k为总变数
vector<int> G[MAXN]; // 邻接表表示二分图
int match[MAXN]; // match[i]表示右边第i个点匹配的是左边的哪点,如果没有匹配则为-1
bool vis[MAXN]; // DFS中标记右边各点是否已经被访问过
//进行深度搜索最大匹配边
bool dfs(int u) {
    int i;
    for (i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        if (!vis[v]) {
            vis[v] = true;
            if (match[v] == -1 || dfs(match[v])) {
                match[v] = u;//对边进行存储
                return true;
            }
        }
    }
    return false;
}
//匈牙利算法
int hungarian() {
    int res = 0;
    memset(match, -1, sizeof(match));
    for (int i = 1; i <= n; i++) {
        memset(vis, false, sizeof(vis));
        if (dfs(i)) res++;
    }
    return res;
}
int main() {
    cin >> n >> m >> k; // 输入左部点数和右部点数
    int u, v;
    int i=0;
    for(;i<k;i++){
        cin >> u >> v ; // 输入边 (u, v),u属于左部,v属于右部
        G[u].push_back(v);
    }
    int max_matches = hungarian(); // 计算最大匹配数
    cout << "最大匹配边数:" << max_matches << endl;
    // 输出最大匹配数
    // 输出最大匹配的所有边
    cout << "最大匹配边为:" << endl;
    for (int v = 1; v <= m; v++) {
        if (match[v] != -1) { // 如果右部点v有匹配
            cout << "Edge: " << match[v] << " - " << v <<endl; // 输出匹配边
        }
    }
    system("pause");
    return 0;
}

测试用例:(两侧顶点数均大于10,且两侧顶点数不相等)

|------------------------------------------------------------------------------------------------------------------------------------------------------|
| |

输出结果:

相关推荐
研究点啥好呢1 小时前
Github热门项目推荐 | 创建你的像素风格!
c++·python·node.js·github·开源软件
_dindong1 小时前
cf1091div2 C.Grid Covering(数论)
c++·算法
沫璃染墨2 小时前
C++ string 从入门到精通:构造、迭代器、容量接口全解析
c语言·开发语言·c++
6Hzlia2 小时前
【Hot 100 刷题计划】 LeetCode 17. 电话号码的字母组合 | C++ 回溯算法经典模板
c++·算法·leetcode
计算机安禾3 小时前
【数据结构与算法】第36篇:排序大总结:稳定性、时间复杂度与适用场景
c语言·数据结构·c++·算法·链表·线性回归·visual studio
unicrom_深圳市由你创科技3 小时前
做虚拟示波器这种实时波形显示的上位机,用什么语言?
c++·python·c#
无限进步_3 小时前
【C++】电话号码的字母组合:从有限处理到通用解法
开发语言·c++·ide·windows·git·github·visual studio
C++ 老炮儿的技术栈3 小时前
GCC编译时无法向/tmp 目录写入临时汇编文件,因为设备空间不足,解决
linux·运维·开发语言·汇编·c++·git·qt
橘颂TA4 小时前
【笔试】算法的暴力美学——牛客 NC213140 :除2!
c++·算法·结构与算法
汀、人工智能4 小时前
[特殊字符] 第66课:跳跃游戏
数据结构·算法·数据库架构·图论·bfs·跳跃游戏