JDOJ-2008: 飞行员配对方案问题

[文章目录]

Description

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

显然是二分图最大匹配问题,匈牙利算法就可以,而当dfs一个点集合时的flag数组只有所属的另一集合才会记录,同时,可以加一条语句,在给flag赋值时将两边的都记录一下。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int m,n,cnt;
int head[110],to[1100000],nxt[1100000],ans,flag[110];
bool v[1100000];
void add(int x,int y)
{
	to[++cnt]=y;
	nxt[cnt]=head[x];
	head[x]=cnt;
}
bool dfs(int a)
{
	for(int y,i=head[a];i;i=nxt[i])
	{
		if(!v[y=to[i]])
		{
			v[y]=1;
			if(flag[y]==0||dfs(flag[y]))
			{
				flag[y]=a;
				return true;
			}
		}
	}
	return false;
}
int main()
{
	scanf("%d%d",&m,&n);
	int x,y;
	while(scanf("%d%d",&x,&y))
	{
		if(!~x)break;
		add(y,x);
		add(x,y);
	}
	for(int i=n;i>m;i--)
	{
		memset(v,0,sizeof(v));
		if(dfs(i)) ans++;
	}
	if(ans==0)
		puts("No Solution!");
	else
	{
		printf("%d\n",ans);
		for(int i=1;i<=m;i++)
			if(flag[i])printf("%d %d\n",i,flag[i]);
	}
	return 0;
}

 

发表评论

邮箱地址不会被公开。 必填项已用*标注