P2756 飞行员配对方案问题

tech2023-12-06  99

P2756 飞行员配对方案问题

题目背景 第二次世界大战期间,英国皇家空军从沦陷国征募了大量外籍飞行员。由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的两名飞行员,其中一名是英国飞行员,另一名是外籍飞行员。在众多的飞行员中,每一名外籍飞行员都可以与其他若干名英国飞行员很好地配合。

题目描述 一共有 n个飞行员,其中有 m 个外籍飞行员和 (n−m) 个英国飞行员,外籍飞行员从 1 到 m 编号,英国飞行员从 m + 1 到 n 编号。 对于给定的外籍飞行员与英国飞行员的配合情况,试设计一个算法找出最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。

输入格式 输入的第一行是用空格隔开的两个正整数,分别代表外籍飞行员的个数 m 和飞行员总数 n。 从第二行起到倒数第二行,每行有两个整数 u, v代表外籍飞行员 u 可以和英国飞行员 v 配合。输入的最后一行保证为 -1 -1,代表输入结束。

输出格式 本题存在 Special Judge。 请输出能派出最多的飞机数量,并给出一种可行的方案。 输出的第一行是一个整数,代表一次能派出的最多飞机数量,设这个整数是 kk。 第 2 行到第 k+1 行,每行输出两个整数 u,v,代表在你给出的方案中,外籍飞行员 u 和英国飞行员 v 配合。这 k 行的 u 与 v 应该互不相同。

输入输出样例 输入

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

说明/提示 【数据范围与约定】

对于 100% 的数据,保证1≤m≤n<100,1≤u≤m<v≤n,同一组配对关系只会给出一次。

【提示】 请注意输入的第一行先读入 m,再读入 n。

思路: 这就是一个最大匹配的模板,真没有什么好说的,看我前面的博客吧!

#include <cstdio> #include <iostream> #include <cstring> using namespace std; const int N=1e4+10; struct node {int u, v, next;} edge[N]; int n, m, a, b, tot, hd[N], ans, link[N]; bool cover[N]; void add(int u, int v) {edge[++tot]=(node){u,v,hd[u]}, hd[u]=tot;} bool find(int x) { for(int i=hd[x]; i; i=edge[i].next) { int y=edge[i].v; if(!cover[y]) { cover[y]=1; int q=link[y]; link[y]=x; if(!q || find(q)) return 1; link[y]=q; } } return 0; } int main() { scanf("%d%d%d%d", &n, &m, &a, &b); while((a!=-1) && (b!=-1)) add(a, b), scanf("%d%d", &a, &b); for(int i=1; i<=n; i++) { memset(cover, 0, sizeof(cover)); if(find(i)) ans++; } printf("%d\n", ans); for(int i=n+1;i<=m;i++) { if(link[i]) printf("%d %d\n", link[i], i); } return 0; }
最新回复(0)