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
  • 相关阅读:
    BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第11章节--为Office和SP解决方式开发集成Apps 集成SP和Office App
    jQuery 处理TextArea
    Raphael的拖动处理
    CSS的position设置
    SVG的内部事件添加
    SVG的a链接
    SVG的text使用
    SVG的path的使用
    SVG的Transform使用
    Java中两个List对比的算法
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10888877.html
Copyright © 2011-2022 走看看