1. 程式人生 > >要成為魔法少女嗎!!1681(二分圖匹配——匈牙利演算法模板題)

要成為魔法少女嗎!!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 }