zoukankan      html  css  js  c++  java
  • 二分图——多重匹配模板hdu1669

    好像多重匹配一般是用网络流来做的。。

    这是匈牙利算法的模板:lim是每个组的上界

    思路是每个组都可以匹配lim个点,那么当点x遇到的组匹配的点数还没有超过lim时,直接匹配即可

    如果已经等于了lim,这时就要从这个组的lim个点里找到一个能匹配到其他组的点(类似于普通匹配的寻找增广路过程)

    int dfs(int x,int lim){
        for(int i=1;i<=m;i++)//枚举每个组 
            if(!vis[i] && mp[x][i]){
                vis[i]=1;
                if(match[i].size()<lim){
                    match[i].push_back(x);
                    return 1;
                } 
                //每个和i匹配的点 
                for(int j=0;j<match[i].size();j++){
                    if(dfs(match[i][j],lim)){
                        match[i][j]=x;
                        return 1; 
                    } 
                } 
            }
        return 0;
    }

    完整代码

    #include<bits/stdc++.h>
    using namespace std;
    #define N 2005
    int n,m,mp[N][N],vis[N];
    vector<int>match[N];
    
    int dfs(int x,int lim){
        for(int i=1;i<=m;i++)//枚举每个组 
            if(!vis[i] && mp[x][i]){
                vis[i]=1;
                if(match[i].size()<lim){
                    match[i].push_back(x);
                    return 1;
                } 
                //每个和i匹配的点 
                for(int j=0;j<match[i].size();j++){
                    if(dfs(match[i][j],lim)){
                        match[i][j]=x;
                        return 1; 
                    } 
                } 
            }
        return 0;
    }
    
    int judge(int lim){
        for(int i=1;i<=n;i++)match[i].clear();
        for(int i=1;i<=n;i++){
            memset(vis,0,sizeof vis);
            if(!dfs(i,lim))return 0;
        } 
        return 1;
    }
    
    char s[N],ch;
    int main(){
        while(cin>>n>>m,n){
            memset(mp,0,sizeof mp);
            for(int i=1;i<=n;i++){
                scanf("%s",s);
                int j;
                while(1){
                    scanf("%d%c",&j,&ch);
                    mp[i][++j]=1;
                    if(ch=='
    ')break;
                }
            }
            int l=0,r=2*n,mid,ans=0;
            while(l<=r){
                mid=l+r>>1;
                if(judge(mid))
                    ans=mid,r=mid-1;
                else l=mid+1;
            }
            cout<<ans<<endl;
        }
    }
    View Code
  • 相关阅读:
    Java通过JNI调用C/C++
    Using HTML5 audio and video
    vmstat输出项解释
    uva 11237
    NN优化方法对照:梯度下降、随机梯度下降和批量梯度下降
    认识与学习bash
    系统崩溃,大圣归来
    连载《一个程序员的生命周期》-25.到工业现场学习业务知识引发的思考
    ZOJ问题(2010浙江大学研究生复试上机题目[找规律] hdoj 3788)
    UIView的几个枚举定义
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10888877.html
Copyright © 2011-2022 走看看