zoukankan      html  css  js  c++  java
  • 51nod 2006 飞行员配对(二分图最大匹配) 裸匈牙利算法 求二分图最大匹配题

    题目:

    题目已经说了是最大二分匹配题,

    查了一下最大二分匹配题有两种解法,

    匈牙利算法和网络流。

    看了一下觉得匈牙利算法更好理解,

    然后我照着小红书模板打了一遍就过了。

    匈牙利算法:先试着把没用过的左边的点和没用过的右边的点连起来,

          如果遇到一个点已经连过就试着把原来的拆掉 把现在这条线连起来看能不能多连上一条线。

    总结来说就是试和拆,试的过程很简单,拆的过程由于使用递归写的,很复杂。很难讲清楚,只能看代码自己理会。

    代码(有注释):

    #include <bitsstdc++.h>
    using namespace std;
    typedef long long ll;
    
    //输入:
    const  int MAXN = 555; // 数组长度
    int n = 200; //n表示左侧的点数
    vector <int> g[MAXN];  // 表示与左边点i相连的右边点
    
    //输出:
    int from[MAXN];//表示最大匹配中与左边点i相连的边
    int tot;  // 二分图最大匹配数
    
    
    bool use[MAXN]; // 左边点的使用标记
    
    
    //匈牙利算法 模板题 ,match和hungary见小红书ACM国际大学生程序设计竞赛 算法与实现
    bool match(int x){
        for(int i = 0;i < g[x].size(); ++i){
            if(!use[g[x][i]]){
                use[g[x][i]] = true;
                if(from[g[x][i]] == -1 || match(from[g[x][i]])){
                    from[g[x][i]] = x;
                    return true;
                }
            }
        }
        return false;
    }
    
    int hungary(){
        tot = 0;
        memset(from,255,sizeof(from));
        for(int i = 1;i <= n; i++){
            memset(use,0,sizeof(use));
            if(match(i)) ++tot;
        }
        return tot;
    }
    
    int main() {
        int m;
        cin >> n >> m;
        int k1,k2;
        cin >> k1 >> k2;
        while(k1 != -1||k2 != -1){
            g[k1].push_back(k2-n);
            cin >> k1 >> k2;
        };
        cout << hungary() << endl;
        return 0;
    }

    模板:http://www.cnblogs.com/zhangjiuding/p/7538876.html

  • 相关阅读:
    socket 第一课
    _getitem__ __setitem__ __delitem__ __len__
    单继承&多继承 注意点
    面对对象 类&对象
    异常检测
    模块导入
    序列化模块注意点 json&pickle
    re模块
    filter和map
    Maven入门
  • 原文地址:https://www.cnblogs.com/zhangjiuding/p/7538564.html
Copyright © 2011-2022 走看看