P2756 飞行员配对方案问题

题目描述

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

输入格式

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

输出格式

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

输入输出样例

输入样例                                                          输出样例
5 10                                                              4
1 7                                                               1 7
1 8                                                               2 9
2 6                                                               3 8
2 9                                                               5 10
2 10
3 7
3 8
4 7
4 8
5 10
-1 -1

解析

可以说是非常简单的二分图模板,如果不会二分图可以去看me的二分图详解+题目

#include <bits/stdc++.h>
using namespace std;
int match[105];
int n,m;
int u,v;
int head[205],vis[205];
struct node{
	int next,to;
}e[20005];
int cnt=0;
void add(int x,int y){
	e[++cnt].to=y;
	e[cnt].next=head[x];
	head[x]=cnt;
}


bool dfs(int x){
	for (int i=head[x];i;i=e[i].next){
		int v=e[i].to;
		if (!vis[v]){
			vis[v]=1;
			if (!match[v]||dfs(match[v])){
				match[v]=x;
				return 1;
			}
		}
	}
	return 0;
}

int ans=0;
int main(){
	scanf("%d%d",&m,&n);
	do{
		scanf("%d%d",&u,&v);
		add(u,v);add(v,u);
	}while(u!=-1&&v!=-1);
	for (int i=1;i<=m;i++){
		memset(vis,0,sizeof(vis));
		if (dfs(i)) ans++;
	}
	printf("%d\n",ans);
	for (int i=m+1;i<=n;i++){
		if (match[i]!=0)
			printf("%d %d\n",match[i],i);
	}
}
posted @ 2021-09-16 17:45  hewt  阅读(42)  评论(0编辑  收藏  举报