要成為魔法少女嗎!!1681(二分圖匹配——匈牙利演算法模板題)
阿新 • • 發佈:2018-12-10
題目描述
酸奶醬是一位魔法少女,並且她很熱衷於點化她的其他小夥伴和她一起成為魔法少女。
現在有一個棘手的問題擺在酸奶醬面前——她有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 }