-网络流-最大流-二分图-最大匹配- [洛谷 P2756][网络流24题]飞行员配对方案问题

题目背景

第二次界大战时期..

题目描述

英国皇家空军从沦陷国征募了大量外籍飞行员。由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其中1 名是英国飞行员,另1名是外籍飞行员。在众多的飞行员中,每一名外籍飞行员都可以与其他若干名英国飞行员很好地配合。如何选择配对飞行的飞行员才能使一次派出最多的飞机。对于给定的外籍飞行员与英国飞行员的配合情况,试设计一个算法找出最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。

对于给定的外籍飞行员与英国飞行员的配合情况,编程找出一个最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。

输入格式

第 1 行有 2 个正整数 m 和 n。n 是皇家空军的飞行员总数(n<100);m 是外籍飞行员数(m<=n)。外籍飞行员编号为 1~m;英国飞行员编号为 m+1~n。

接下来每行有 2 个正整数 i 和 j,表示外籍飞行员 i 可以和英国飞行员 j 配合。最后以 2个-1 结束。

输出格式

第 1 行是最佳飞行员配对方案一次能派出的最多的飞机数 M。接下来 M 行是最佳飞行员配对方案。每行有 2个正整数 i 和 j,表示在最佳飞行员配对方案中,飞行员 i 和飞行员 j 配对。如果所求的最佳飞行员配对方案不存在,则输出‘No Solution!’。

输入样例

5 10
1 7
1 8
2 6
2 9
2 10
3 7
3 8
4 7
4 8
5 10
-1 -1

输出样例

4
1 7
2 9
3 8
5 10

Solution

把源点都连向皇家空军,把外籍飞行员连向汇点,然后再根据题意连边。

当时这道题我其实用的是匈牙利做的

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#define MAXN 1002
#define INF 2000000000
namespace STman {
template <typename Tp>
inline void read(Tp &x) {
#define C getchar()
Tp f = 1;
x = 0;
char k = C;
while (k < '0' || k > '9') {
if (k == '-') f = -1;
k = C;
}
while (k >= '0' && k <= '9') {
x = x * 10 + k - '0';
k = C;
}
x = x * f;
#undef C
}
template <typename Tp>
inline void write(Tp x) {
if (x < 0) putchar('-') , x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
template <typename Tp>
inline Tp max(Tp a , Tp b) {
if (a > b) return a;
else return b;
}
template <typename Tp>
inline Tp min(Tp a , Tp b) {
if (a < b) return a;
else return b;
}
template <typename Tp>
inline void swap(Tp &a , Tp &b) {
Tp t = a;
a = b;
b = a;
}
template <typename Tp>
inline Tp abs(Tp &a) {
if (a < 0) return -a;
else return a;
}
inline void sp() {
putchar(32);
}
inline void et() {
putchar(10);
}
}
using namespace STman;
struct Edge {
int v , nx;
}e[MAXN];
int mc[MAXN] , vis[MAXN] , n , m , ans , x , y , head[MAXN] , ecnt;
void add(int f , int t) {
e[++ecnt] = (Edge) {t , head[f]};
head[f] = ecnt;
}
bool Hungary(int k) {
for (int i = head[k] ; i ; i = e[i].nx) {
int to = e[i].v;
if (!vis[to]) {
vis[to] = 1;
if (!mc[to] || Hungary(mc[to])) {
mc[to] = k;
return 1;
}
}
}
return 0;
}
int main() {
read(m) , read(n);
read(x) , read(y);
while (x != -1 && y != -1) {
read(x) , read(y);
add(x , y);
}
for (int i = 1 ; i <= m ; i++) {
ans += Hungary(i);
memset(vis , 0 , sizeof(vis));
}
write(ans) , et();
for (int i = m + 1 ; i <= n ; i++) {
if (mc[i]) write(mc[i]) , sp() , write(i) , et();
}
return 0;
}
文章作者: RiverFun
文章链接: https://stevebraveman.github.io/blog/2019/01/22/59/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 RiverFun

评论