C++ 图论算法:二分图最大匹配

图论算法:二分图最大匹配 对应蓝桥云课 代码框架见下

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

#define maxn 510
#define maxm 510

vector<int> adj[maxn]; //ad[i][j]代表i号左边的点的第j条边对应的右边的那个顶点
int pre[maxm];         //pre[i]代表和右边顶点i匹配的左边顶点编号
bool visit[maxm];      //visit[i]代表右边的顶点i是否产生了匹配
int n, m;              //n代表左边点集数量,m代表右边点集数量

void Hungarian_Init(int n_, int m_) {
    n = n_ , m = m_ ;
    memset(pre, -1, sizeof(pre));
    for (int i = 1; i <= n; ++i) {
        adj[i].clear();
    }
}

void Hungarian_AddEdge(int u, int v) {
    adj[u].push_back(v);
}

bool Hungarian_findMatch(int u) {
    for (int i = 0; i < adj[u].size(); ++i) {
        int v = adj[u][i];
        if (!visit[v]) {
            visit[v] = true;
            int vpre = pre[v];
            pre[v] = u;
            if (vpre == -1 || Hungarian_findMatch(vpre)) {
                return true;
            }
            pre[v] = vpre;
        }
    }
    return false;
}

int Hungarian_GetMaxMatch() {
    int cnt = 0;
    for (int i = 1; i <= n; ++i) {
        memset(visit, false, sizeof(visit));
        if (Hungarian_findMatch(i)) {
            cnt++;
        }
    }
    return cnt;
}

int main()
{
    int n, m, k;
    cin >> n >> m >> k;
    Hungarian_Init(n, m);
    for (int i = 0; i < k; ++i) {
        int x, y;
        cin >> x >> y;
        Hungarian_AddEdge(x, y);
    }
    cout << Hungarian_GetMaxMatch() << endl;
    // 请在此输入您的代码
    return 0;
}

代码练习1 对应蓝桥云课 职位匹配 代码见下

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

#define maxn 1010
#define maxm 1010

vector<int> adj[maxn]; //ad[i][j]代表i号左边的点的第j条边对应的右边的那个顶点
int pre[maxm];         //pre[i]代表和右边顶点i匹配的左边顶点编号
bool visit[maxm];      //visit[i]代表右边的顶点i是否产生了匹配
int n, m;              //n代表左边点集数量,m代表右边点集数量

void Hungarian_Init(int n_, int m_) {
    n = n_ , m = m_ ;
    memset(pre, -1, sizeof(pre));
    for (int i = 1; i <= n; ++i) {
        adj[i].clear();
    }
}

void Hungarian_AddEdge(int u, int v) {
    adj[u].push_back(v);
}

bool Hungarian_findMatch(int u) {
    for (int i = 0; i < adj[u].size(); ++i) {
        int v = adj[u][i];
        if (!visit[v]) {
            visit[v] = true;
            int vpre = pre[v];
            pre[v] = u;
            if (vpre == -1 || Hungarian_findMatch(vpre)) {
                return true;
            }
            pre[v] = vpre;
        }
    }
    return false;
}

int Hungarian_GetMaxMatch() {
    int cnt = 0;
    for (int i = 1; i <= n; ++i) {
        memset(visit, false, sizeof(visit));
        if (Hungarian_findMatch(i)) {
            cnt++;
        }
    }
    return cnt;
}

int main()
{
  int n, m;
  //n: 职位数量
  //m: 求职者数量
  cin >> n >> m;
  Hungarian_Init(m, n);
  for(int i=1; i <= m; ++i){
    int k;
    cin >> k;
    while(k--){
      int x;
      cin >> x;
      Hungarian_AddEdge(i, x);
    }
  }  
  cout << Hungarian_GetMaxMatch() << endl;
    return 0;
}

代码练习2 对应蓝桥云课 长方形的覆盖 代码见下

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

#define maxn 510
#define maxm 510

vector<int> adj[maxn]; //ad[i][j]代表i号左边的点的第j条边对应的右边的那个顶点
int pre[maxm];         //pre[i]代表和右边顶点i匹配的左边顶点编号
bool visit[maxm];      //visit[i]代表右边的顶点i是否产生了匹配
int n, m;              //n代表左边点集数量,m代表右边点集数量

void Hungarian_Init(int n_, int m_) {
    n = n_, m = m_;
    memset(pre, -1, sizeof(pre));
    for (int i = 1; i <= n; ++i) {
        adj[i].clear();
    }
}

void Hungarian_AddEdge(int u, int v) {
    adj[u].push_back(v);
}

bool Hungarian_findMatch(int u) {
    for (int i = 0; i < adj[u].size(); ++i) {
        int v = adj[u][i];
        if (!visit[v]) {
            visit[v] = true;
            int vpre = pre[v];
            pre[v] = u;
            if (vpre == -1 || Hungarian_findMatch(vpre)) {
                return true;
            }
            pre[v] = vpre;
        }
    }
    return false;
}

int Hungarian_GetMaxMatch() {
    int cnt = 0;
    for (int i = 1; i <= n; ++i) {
        memset(visit, false, sizeof(visit));
        if (Hungarian_findMatch(i)) {
            cnt++;
        }
    }
    return cnt;
}

char c[25][25];
int dir[4][2] = {
  {0, 1}, {1, 0}, {0, -1}, {-1, 0}
};

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        cin >> c[i];
    }
    Hungarian_Init(n * n, n * n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            if ((i + j) & 1) {
                for (int k = 0; k < 4; ++k) {
                    int di = i + dir[k][0];
                    int dj = j + dir[k][1];
                    if (dj < 0 || di == n || dj < 0 || dj == n) {
                        continue;
                    }
                    if (c[i][j] == '1' || c[di][dj] == '1') {
                        continue;
                    }
                    Hungarian_AddEdge(i * n + j + 1, di * n + dj + 1);
                }
            }
        }
    }
    cout << Hungarian_GetMaxMatch() << endl;
    return 0;
}
相关推荐
Once_day4 分钟前
C++之《程序员自我修养》读书总结(1)
c语言·开发语言·c++·程序员自我修养
Trouvaille ~14 分钟前
【Linux】TCP Socket编程实战(一):API详解与单连接Echo Server
linux·运维·服务器·网络·c++·tcp/ip·socket
偷吃的耗子19 分钟前
【CNN算法理解】:CNN平移不变性详解:数学原理与实例
人工智能·算法·cnn
坚果派·白晓明25 分钟前
在鸿蒙设备上快速验证由lycium工具快速交叉编译的C/C++三方库
c语言·c++·harmonyos·鸿蒙·编程语言·openharmony·三方库
小镇敲码人32 分钟前
深入剖析华为CANN框架下的Ops-CV仓库:从入门到实战指南
c++·python·华为·cann
dazzle1 小时前
机器学习算法原理与实践-入门(三):使用数学方法实现KNN
人工智能·算法·机器学习
那个村的李富贵1 小时前
智能炼金术:CANN加速的新材料AI设计系统
人工智能·算法·aigc·cann
张张努力变强2 小时前
C++ STL string 类:常用接口 + auto + 范围 for全攻略,字符串操作效率拉满
开发语言·数据结构·c++·算法·stl
万岳科技系统开发2 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
小镇敲码人2 小时前
探索CANN框架中TBE仓库:张量加速引擎的优化之道
c++·华为·acl·cann·ops-nn