要成为魔法少女吗!!1681(二分图匹配——匈牙利算法模板题)

题目描述

酸奶酱是一位魔法少女,并且她很热衷于点化她的其他小伙伴和她一起成为魔法少女。

现在有一个棘手的问题摆在酸奶酱面前——她有M套成为魔法少女不可缺少的魔法战斗服,以及N个想成为魔法少女的小伙伴。魔法战斗服是有灵性的,它有想要跟随的主人。酸奶酱想尽可能多的把更多的魔法战斗服分给她的小伙伴,她现在想知道最多能有几套魔法战斗服能被交到她的小伙伴手里。

注意:一位小伙伴只能拿一件魔法战斗服,一件魔法战斗服也只能交给一位小伙伴。

输入

第一行为两个整数N和M,分别表示小伙伴的数量和魔法战斗服的数量。(0<=N,M<=100)

接下来M行,第i行的第一个整数K表示第i件魔法战斗服想要跟随的主人的数量。接下来K个整数num,表示魔法战斗服想要跟随的主人编号。(0<=K,num<=N)

输出

对于每组数据,输出一行,为最多能送出的魔法战斗服的数量。

输入样例

3 4
1 2
3 1 2 3
1 1
0

输出样例

3


二分图匹配(匈牙利算法)模板题
https://blog.csdn.net/C20180630/article/details/70175814

图的存储采用邻接矩阵
匹配关系的记录由于是两个元素之间的关系,且一个元素最多与一个元素有关系,故采用一个一维数组match即可,match[v]=u表示v(v属于右边点集的元素)

AC代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=107;

int m,n;
int t[maxn][maxn];
bool vis[maxn];
int match[maxn];
bool dfs(int u){
    for(int v=1;v<=n;v++)
        if(t[u][v]&&!vis[v]){
            vis[v]=1;
            if(match[v]==-1||dfs(match[v])){
                match[v]=u;
                return 1;
            }
        }
    return 0;
}
int maxmatch()//匈牙利算法主函数
{
    int ans=0;
    memset(match,-1,sizeof(match));
    for(int i=0;i<=m;i++)
    {
        memset(vis,false,sizeof(vis)) ;
        ans += dfs(i);
    }
    return ans ;
}
int main(){
    int T;
    int num;
    int ans;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;++i){
        scanf("%d",&T);
        for(int j=1;j<=T;++j){
            scanf("%d",&num);
            t[i][num]=1;
        }
    }
    ans=maxmatch();
    printf("%d",ans);
}
 
 
 

二分图模板

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7 const int maxn=107;
 8 //m为点集U的元素个数,n为点集V的元素个数
 9 //t储存U和V的关系(即关系图),有关系置1,没有关系置0
10 //vis用于DFS中标记是否被访问过
11 //match存储匹配关系,match[v]=u表示建立了u和v的匹配,没有匹配关系时置-1
12 int m,n;
13 int t[maxn][maxn];
14 bool vis[maxn];
15 int match[maxn];
16 bool dfs(int u){
17     for(int v=1;v<=n;v++)
18         if(t[u][v]&&!vis[v]){
19             vis[v]=1;
20             if(match[v]==-1||dfs(match[v])){
21                 match[v]=u;
22                 return 1;
23             }
24         }
25     return 0;
26 }
27 int maxmatch()//匈牙利算法主函数
28 {
29     int ans=0;
30     memset(match,-1,sizeof(match));
31     for(int i=0;i<=m;i++)
32     {
33         memset(vis,false,sizeof(vis)) ;
34         ans += dfs(i);
35     }
36     return ans ;
37 }
38 void init(){
39     scanf("%d%d",&n,&m);
40     //初始化图t
41 }
42 int main(){
43     
44     int ans;
45     ans=maxmatch();
46     printf("%d",ans);
47 }
 

猜你喜欢

转载自www.cnblogs.com/loganlzj/p/10098993.html