51nod 2006 二分图最大匹配
第二次世界大战时期,英国皇家空军从沦陷国征募了大量外籍飞行员。由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2名飞行员,其中1名是英国飞行员,另1名是外籍飞行员。在众多的飞行员中,每一名外籍飞行员都可以与其他若干名英国飞行员很好地配合。如何选择配对飞行的飞行员才能使一次派出最多的飞机。对于给定的外籍飞行员与英国飞行员的配合情况,试设计一个算法找出最佳飞行员配对方案,使皇家空 军一次能派出最多的飞机 。对于给定的外籍飞行员与英国飞行员的配合情况,编程找出一个最佳飞行员配对方案, 使皇家空军一次能派出最多的飞机。
Input
第1行有2个正整数 m 和 n。n 是皇家空军的飞行 员总数(n<100);m 是外籍飞行员数。外籍飞行员编号为 1~m;英国飞行员编号为 m+1~n。接下来每行有 2 个正整数 i 和 j,表示外籍飞行员 i 可以和英国飞行员 j 配合。输入最后以 2 个-1 结束。
Output
第 1 行是最佳飞行 员配对方案一次能派出的最多的飞机数 M。如果所求的最佳飞行员配对方案不存在,则输出‘No Solution!’。
Input示例
5 10 1 7 1 8 2 6 2 9 2 10 3 7 3 8 4 7 4 8 5 10 -1 -1
Output示例
4
前天看到这题,无从下手,然后花了两天多的时间把网络流的基本知识学了下,刷了几道最大流和二分图最大匹配,今天在来看下这道题,发现就是个模板题。
直接贴代码。
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <vector> 5 using namespace std; 6 const int N = 110; 7 int edge[N][N], vis[N], match[N]; 8 int n, m; 9 10 bool dfs(int v) { 11 for(int i = 1; i <= m; i ++) { 12 if(edge[i][v] && !vis[i]) { 13 vis[i] = 1; 14 if(match[i] == -1 || dfs(match[i])) { 15 match[i] = v; 16 return true; 17 } 18 } 19 } 20 return false; 21 } 22 int max_match() { 23 int res = 0; 24 memset(match, -1, sizeof(match)); 25 for(int i = m+1; i <= n; i ++) { 26 if(match[i] < 0) { 27 memset(vis, 0, sizeof(vis)); 28 if(dfs(i)) res++; 29 } 30 } 31 return res; 32 } 33 int main() { 34 cin>>m>>n; 35 memset(edge, 0, sizeof(edge)); 36 int u, v; 37 while(cin >> u >> v) { 38 if(u==-1 && v == -1)break; 39 edge[u][v] = 1; 40 } 41 printf("%d\n",max_match()); 42 return 0; 43 }