搭配飞行员
题面:
飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾驶员。由于种种原因,例如相互配合的问题,有些驾驶员不能在同一架飞机上飞行,问如何搭配驾驶员才能使出航的飞机最多。
因为驾驶工作分工严格,两个正驾驶员或两个副驾驶员都不能同机飞行。
2<=n<=100
思路: 二分图最大匹配,二分图上跑一下最大流即可
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int N = 10005;
int n, m, ss, tt;
int dis[N];
int cur[N];
queue<int> q;
struct Edge {
int to;
int value;
int next;
} e[N * 4];
int head[N], cnt = -1;
void add(int from, int to, int value) {
cnt++;
e[cnt].to = to;
e[cnt].value = value;
e[cnt].next = head[from];
head[from] = cnt;
}
bool bfs(int s, int t) {
q = queue<int>();
memset(dis, -1, sizeof(dis));
dis[s] = 0;
q.push(s);
while (!q.empty()) {
int x = q.front();
q.pop();
for (int i = head[x]; i > -1; i = e[i].next) {
int now = e[i].to;
if (dis[now] == -1 && e[i].value != 0) {
dis[now] = dis[x] + 1;
q.push(now);
}
}
}
return dis[t] != -1;
}
int dfs(int x, int t, int maxflow) {
if (x == t)
return maxflow;
int ans = 0;
for (int i = cur[x]; i > -1; i = e[i].next) {
int now = e[i].to;
if (dis[now] != dis[x] + 1 || e[i].value == 0 || ans >= maxflow)
continue;
cur[x] = i;
int f = dfs(now, t, min(e[i].value, maxflow - ans));
e[i].value -= f;
e[i ^ 1].value += f;
ans += f;
}
return ans;
}
int Dinic(int s, int t) {
int ans = 0;
while (bfs(s, t)) {
memcpy(cur, head, sizeof(head));
ans += dfs(s, t, INF);
}
return ans;
}
int main() {
memset(head, -1, sizeof(head));
scanf("%d%d", &n, &m);
int a, b;
while (~scanf("%d%d", &a, &b)) {
add(a, b, 1);
add(b, a, 0);
}
ss = 0, tt = n + 1;
for (int i = 1; i <= m; i++) {
add(ss, i, 1);
add(i, ss, 0);
}
for (int i = m + 1; i <= n; i++) {
add(i, tt, 1);
add(tt, i, 0);
}
printf("%d\n", Dinic(ss, tt));
return 0;
}