zoukankan      html  css  js  c++  java
  • 匈牙利算法模板

    邻接矩阵:

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <queue>
    using namespace std;
    
    int mp[2100][2100]; // 图的存储矩阵
    int n, m;
    int ans;
    bool vis[2100]; // 当前搜索过程中是否被访问过
    int link[2100]; // y集合中的点在x集合中的匹配点 -1表示未匹配
    
    bool find_(int x) {
        for (int i=1; i<=n; ++i) {
            if (mp[x][i] && !vis[i]) { // 有边相连
                vis[i] = 1; // 标记该点
                if (link[i] == -1 || find_(link[i])) { //该点未匹配 或者匹配的点能找到增光路
                    link[i] = x; // 删掉偶数条边 加进奇数条边
                    return true; // 找到增光路
                }
            }
        }
        return false;
    }
    
    void match() {
        //初始化
        ans = 0;
        memset(link, -1, sizeof(link));
    
        for (int i=1; i<=n; ++i) {
            memset(vis, 0, sizeof(vis)); // 从集合的每个点依次搜索
            if (find_(i)) // 如果能搜索到 匹配数加1
                ans++;
        }
        return;
    }
    
    int main() {
        while(cin >> n >> m) {
            memset(mp, 0, sizeof(mp));
    
            for (int i=0; i<m; ++i) {
                int x, y;
                cin >> x >> y;
                mp[x][y] = 1;
                mp[y][x] = 1;
            }
    
            //判断是不是二分图 过
    
            match();
            cout << ans/2 << endl;
        }
        return 0;
    }
    

    邻接表:

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <queue>
    #define maxn 205
    using namespace std;
    
    int n, m;
    int ans;
    bool vis[maxn]; // 当前搜索过程中是否被访问过
    int link[maxn]; // y集合中的点在x集合中的匹配点 -1表示未匹配
    
    int head[maxn];
    int tot;
    
    struct Node {
        int v, nxt;
    }edge[maxn*maxn];
    
    void addEdge(int u, int v) {
        edge[tot].v = v;
        edge[tot].nxt = head[u];
        head[u] = tot++;
    }
    
    bool find_(int x) {
        for (int i=head[x]; i!=-1; i=edge[i].nxt) { // 遍历以x为顶点的所有边
            int v = edge[i].v;
            if (vis[v]) continue; // 如果v在当前寻找增光路过程中被访问过
            vis[v] = 1; // 标记访问
            if (link[v] == -1 || find_(link[v])) { // 如果v点没有被匹配过 或者 匹配点能找到增光路
                link[v] = x; // 增广路奇偶倒置
                return true;
            }
        }
        return false;
    }
    
    void match() {
        ans = 0;
        memset(link, -1, sizeof(link));
    
        for (int i=1; i<=n; ++i) {
            memset(vis, 0, sizeof(vis)); // 从集合的每个点依次搜索
            if (find_(i)) // 如果能搜索到 匹配数加1
                ans++;
        }
        return;
    }
    
    
    int main() {
        while(cin >> n >> m) {
            tot = 0;
            memset(head, -1, sizeof(head));
            for (int i=0; i<m; ++i) {
                int x, y;
                cin >> x >> y;
                addEdge(x, y);
                addEdge(y, x);
            }
    
            match();
            cout << ans/2 << endl;
        }
        return 0;
    }
    

      

  • 相关阅读:
    java 闭包(转)
    设计模式之工厂
    java研发工作组环境架设
    [每日一题jQuery] jQuery选择器总结:进一步过滤、同级操作、后代操作
    [工具] 解决sublime text运行javascript console无输出问题
    [工具]web开发时自动刷新网页:liveReload
    [每日一题JS] 正则表达式
    [工具]sublime text2前端开发利器
    |原创|unity 4.3 2D功能SpriteRenderer修改颜色的方法
    unity 获取系统时间
  • 原文地址:https://www.cnblogs.com/icode-girl/p/5398049.html
Copyright © 2011-2022 走看看