思路:
设置源点为 0,汇点为 n + 1,源点向飞行员引弧,容量为 1,飞行员和副飞行员引弧,容量为 1,副飞行员向 汇点引弧,容量为 1,求最大流。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int MAXN = 110;
const int INFS = 0x3FFFFFFF;
struct edge {
int from, to, cap, flow;
edge(int _from, int _to, int _cap, int _flow)
: from(_from), to(_to), cap(_cap), flow(_flow) {}
};
struct ISAP {
vector<edge> edges;
vector<int> G[MAXN];
int s, t, n;
int d[MAXN], p[MAXN], cur[MAXN], gap[MAXN];
bool vis[MAXN];
void clearall(int n) {
this->n = n;
edges.clear();
for (int i = 0; i < n; i++)
G[i].clear();
}
void addedge(int u, int v, int cap) {
edges.push_back(edge(u, v, cap, 0));
edges.push_back(edge(v, u, 0, 0));
G[u].push_back(edges.size() - 2);
G[v].push_back(edges.size() - 1);
}
bool BFS() {
queue<int> Q;
memset(d, 0, sizeof(d));
memset(vis, false, sizeof(vis));
vis[t] = true;
Q.push(t);
while (!Q.empty()) {
int x = Q.front(); Q.pop();
for (int i = 0; i < G[x].size(); i++) {
edge& e = edges[G[x][i]^1];
if (e.cap > e.flow && !vis[e.from]) {
vis[e.from] = true;
d[e.from] = d[x] + 1;
Q.push(e.from);
}
}
}
return vis[s];
}
int augment() {
int x = t, f = INFS;
while (x != s) {
edge& e = edges[p[x]];
f = min(f, e.cap - e.flow);
x = e.from;
}
x = t;
while (x != s) {
edges[p[x]].flow += f;
edges[p[x]^1].flow -= f;
x = edges[p[x]].from;
}
return f;
}
int maxflow(int s, int t) {
this->s = s, this->t = t;
BFS();
memset(cur, 0, sizeof(cur));
memset(p, 0, sizeof(p));
memset(gap, 0, sizeof(gap));
for (int i = 0; i < n; i++)
gap[d[i]] += 1;
int x = s, flow = 0;
while (gap[s] < n) {
if (x == t) {
flow += augment();
x = s;
}
bool flag = false;
for (int i = cur[x]; i < G[x].size(); i++) {
edge& e = edges[G[x][i]];
if (d[x] == d[e.to] + 1 && e.cap > e.flow) {
flag = true;
cur[x] = i;
p[e.to] = G[x][i];
x = e.to; break;
}
}
if (!flag) {
int m = n - 1;
for (int i = 0; i < G[x].size(); i++) {
edge& e = edges[G[x][i]];
if (e.cap > e.flow) m = min(m, d[e.to]);
}
if (--gap[d[x]] == 0) break;
gap[d[x] = m+1] += 1;
cur[x] = 0;
if (x != s) x = edges[p[x]].from;
}
}
return flow;
}
};
ISAP sap;
int main() {
freopen("flyer.in", "r", stdin);
freopen("flyer.out", "w", stdout);
int n, n1;
scanf("%d%d", &n, &n1);
int u, v;
sap.clearall(n + 2);
while (scanf("%d%d", &u, &v) != EOF) {
sap.addedge(u, v, 1);
}
int s = 0, t = n + 1;
for (int i = 1; i <= n1; i++)
sap.addedge(s, i, 1);
for (int i = n1+1; i <= n; i++)
sap.addedge(i, t, 1);
printf("%d\n", sap.maxflow(s, t));
return 0;
}