二分图——多重匹配模板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==‘\n‘)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;
    }
}

原文地址:https://www.cnblogs.com/zsben991126/p/10888877.html

时间: 2024-10-11 00:57:34

二分图——多重匹配模板hdu1669的相关文章

hihoCoder 1393 网络流三&#183;二分图多重匹配(Dinic求二分图最大多重匹配)

#1393 : 网络流三·二分图多重匹配 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来. 小Hi和小Ho作为班上的班干部,统计分配比赛选手的重任也自然交到了他们手上. 已知小Hi和小Ho所在的班级一共有N名学生(包含小Hi和小Ho),编号依次为1..N. 运动会一共有M项不同的比赛,编号为1..M.第i项比赛每个班需要派出m[i]名选手参加. 根据小Hi和小Ho的统计,编号为i的学生表示最多同时参加

hiho 第117周 二分图多重匹配,网络流解决

描述 学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来. 小Hi和小Ho作为班上的班干部,统计分配比赛选手的重任也自然交到了他们手上. 已知小Hi和小Ho所在的班级一共有N名学生(包含小Hi和小Ho),编号依次为1..N. 运动会一共有M项不同的比赛,编号为1..M.第i项比赛每个班需要派出m[i]名选手参加. 根据小Hi和小Ho的统计,编号为i的学生表示最多同时参加a[i]项比赛,并且给出他所擅长的b[i]项比赛的编号. 小Hi和小Ho希望将每个学生都安排到他所擅长的比赛项目,

kuangbin带你飞 匹配问题 二分匹配 + 二分图多重匹配 + 二分图最大权匹配 + 一般图匹配带花树

二分匹配:二分图的一些性质 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图. 1.一个二分图中的最大匹配数等于这个图中的最小点覆盖数 König定理是一个二分图中很重要的定理,它的意思是,一个二分图中的最大匹配数等于这个图中的最小点覆盖数.如果你还不知道什么是最小点覆盖,我也在这里说一下:假如选

HDU 3605 Escape(二分图多重匹配问题)

Escape Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 10382    Accepted Submission(s): 2485 Problem Description 2012 If this is the end of the world how to do? I do not know how. But now scient

POJ 2289 Jamie&#39;s Contact Groups 二分图多重匹配

题意:n个人,m个组,给出每个人可以分到那些组中,把每个人都分进某组中,问最大组的人数最小为?n<=1e3,m<=500,二分图多重匹配 左边为人 右边为分组 可以多个人对一个组由于要求最大组的最小人数 二分答案x,右边点最多流量为x,判断匹配数是否n即可. #include <iostream> #include <cstdio> #include <cstring> using namespace std; typedef long long ll; t

HDU 3605 Escape【二分图多重匹配】

题意: 有n个人去m个星球  告诉你每个人想去哪些星球和每个星球最多容纳多少人,问能不能让所有人都满足 分析: 二分图多重匹配 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 using namespace std; 6 7 const int maxn = 100005; 8 const int maxm = 15; 9 10

Poj 2289 Jamie&#39;s Contact Groups (二分+二分图多重匹配)

题目链接: Poj 2289 Jamie's Contact Groups 题目描述: 给出n个人的名单和每个人可以被分到的组,问将n个人分到m个组内,并且人数最多的组人数要尽量少,问人数最多的组有多少人? 解题思路: 二分图多重匹配相对于二分匹配来说不再是节点间的一一对应,而是Xi可以对应多个Yi.所以我们就需要一个限制(Xi最多匹配几个Yi).当Yi需要匹配Xi的时候,Xi的匹配未到上限,直接匹配,否则进行增广路.其实是二分图多重匹配的模板题,再套一个二分枚举最多组的人数就OK咯.下面就上板

hdu 3605 Escape (二分图多重匹配)

Escape Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4298    Accepted Submission(s): 1129 Problem Description 2012 If this is the end of the world how to do? I do not know how. But now scient

二分图多重匹配问题

二分图多重匹配问题 #include <iostream> #include <cstdio> #include <cstring> #include <vector> using namespace std; const int maxn = 100005; const int maxm = 15; int cap[maxm]; int Link[maxm][maxn]; int vLink[maxm]; int mat[maxn][maxm]; int