• 匈牙利算法 求二分图最大匹配


    一直没有学习匈牙利算法,因为网络流实现匹配的功能已经足够强大了。

    但今天这道题【BZOJ1191】用网络流实在难以解决动态匹配,而鉴于匈牙利算法实现的代码复杂度极小,所以今天学习一下。


    匈牙利算法用于解决二分图匹配问题,主要思想是增广路,对于当前左点u,若能找到一个相连的未匹配的右点v,则直接匹配,否则进行尝试更改其他已匹配的右点匹配的左点的匹配对象【递归】,若成功则匹配成功


    二分图匹配问题还有很多变式:

    最小点覆盖集 = 最大点独立集 = 最大匹配

    最小路径覆盖数 = 点数 - 最大匹配


    上题:

    BZOJ1191

    大意:二分图匹配= =

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long int
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define fo(i,x,y) for (int i = (x); i <= (y); i++)
    #define Redge(u) for (int k = head[u]; k != -1; k = edge[k].next)
    using namespace std;
    const int maxn = 1005,maxm = 100005,INF = 1000000000;
    inline int read(){
    	int out = 0,flag = 1;char c = getchar();
    	while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
    	while (c >= 48 && c <= 57) {out = out * 10 + c - 48; c = getchar();}
    	return out * flag;
    }
    int n,m,lk[maxn],vis[maxn];
    int head[maxn],nedge = 0;
    struct EDGE{int to,next;}edge[maxm];
    inline void build(int u,int v){
    	edge[nedge] = (EDGE){v,head[u]};
    	head[u] = nedge++;
    }
    bool find(int u){
    	int to;
    	Redge(u) if (!vis[to = edge[k].to]){
    		vis[to] = true;
    		if (!lk[to] || find(lk[to])){
    			lk[to] = u;
    			return true;
    		}
    	}
    	return false;
    }
    int main()
    {
    	fill(head,head + maxn,-1);
    	int ans = 0;
    	n = read(); m = read();
    	REP(i,m) build(i,read()),build(i,read());
    	REP(i,m){
    		memset(vis,0,sizeof(vis));
    		if (find(i)) ans++;
    		else break;
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    


  • 相关阅读:
    男子汉要响当当面对自己写出的程序
    北京天气变化,记下它
    面向对象的设计原则-类设计原则
    JSSCript打开X3,并设置IE窗口样式
    “做人做事”的信条
    工作角色的定位
    JS语法字典网友总结
    处理多个选择结果
    Jquery获得控件值的方法
    选择器
  • 原文地址:https://www.cnblogs.com/Mychael/p/8282825.html
Copyright © 2020-2023  润新知