2006 飞行员配对(二分图最大匹配)
题目来源: 网络流24题
基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
收藏
关注
第二次世界大战时期,英国皇家空军从沦陷国征募了大量外籍飞行员。由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的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
二分匹配模板题
#include <iostream> #include <algorithm> #include <cstring> using namespace std; #define maxn 1000 int n, m; int a, b; int man[maxn]; bool line[maxn][maxn]; bool check[maxn]; bool find(int x) { for (int i = m + 1; i <= n + m; i++) { if (line[x][i] && !check[i]) { check[i] = true; // 说明 i 尝试被分配 目前要么已经被分配要么即将被分配给 x if (man[i] == 0 || find(man[i])) { man[i] = x; return true; } } } return false; } int main() { while (cin >> m >> n) { memset(line, false, sizeof(line)); memset(man, 0, sizeof(man)); while (cin >> a >> b) { if (a == -1 && b == -1) { break; } // 序号 为 a 的人对 序号为 b 的人有关系 line[a][b] = true; } int sum = 0; for (int i = 1; i <= m; i++) { memset(check, false, sizeof(check)); if (find(i)) { sum++; } } if (sum == 0) { cout << "No Solution!" << endl; } else { cout << sum << endl; } } return 0; }