您的位置:首页 > 理论基础 > 计算机网络

飞行员配对方案问题

2017-03-15 14:02 423 查看

问题描述

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


编程任务

对于给定的外籍飞行员与英国飞行员的配合情况,编程找出一个最佳飞行员配对方案使皇家空军一次能派出最多的飞机。


数据输入

由文件input.txt提供输入数据。文件第1 行有 2个正整数m和 n。n是皇家空军的飞行员总数(n<100);m是外籍飞行员数。外籍飞行员编号
为 1~m;英国飞行员编号为 m+1~n。接下来每行有2个正整数i和j,表示外籍飞行员i可以和英国飞行员j配合。文件最后以 2个-1 结束。


结果输出

程序运行结束时,将最佳飞行员配对方案输出到文件 output.txt 中。第 1 行是最佳飞行员配对方案一次能派出的最多的飞机数 M。接下来
M 行是最佳飞行员配对方案。每行有 2个正整数 i和j,表示在最佳飞行员配对方案中,飞行员i和飞行员j配对。
如果所求的最佳飞行员配对方案不存在,则输出‘No Solution!’ 。


输入文件示例

input.txt
5 10
1 7
1 8
2 6
2 9
2 10
3 7
3 8
4 7
4 8
5 10
-1 -1


输出文件示例

output.txt
4
1 7
2 9
3 8
5 10


题解

二分图匹配问题,可以用网络流或匈牙利算法求解,然而蒟蒻并不会匈牙利算法这样高端的东西,于是用网络流水过。

【这题我应该在1.23发题解才对

CODE:

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int INF=1e9;
struct aa
{
int next,to,remain;
}a[10005];
int head[105];
int cur[105];
int S[105];
int deep[105];
int n,m,x,y,num=-1,ans;
inline void read(int &n)
{
n=0;
char c;
bool b=0;
while((c=getchar())==' '||c=='\n'||c=='\r');
if(c=='-') b=1;
else n=c-48;
while(isdigit(c=getchar())) n=n*10+c-48;
if(b) n*=-1;
}
inline void add(int from,int to)
{
a[++num].next=head[from];
a[num].to=to;
a[num].remain=1;
head[from]=num;
a[++num].next=head[to];
a[num].to=from;
head[to]=num;
}
inline bool bfs(int s,int t)
{
memset(deep,0x7f,sizeof(deep));
memcpy(cur,head,sizeof(cur));
queue<int> q;
q.push(s),deep[s]=0;
while(!q.empty())
{
int tmp=q.front();q.pop();
for(int i=head[tmp];i!=-1;i=a[i].next)
if(deep[a[i].to]>INF&&a[i].remain) deep[a[i].to]=deep[tmp]+1,q.push(a[i].to);
}
return deep[t]<INF;
}
inline int dfs(int s,int t,int limit)
{
if(!limit||s==t) return limit;
int ans=0,tmp;
for(int i=cur[s];i!=-1;i=a[i].next)
{
cur[s]=i;
if(deep[a[i].to]==deep[s]+1&&(tmp=dfs(a[i].to,t,min(limit,a[i].remain))))
{
ans+=tmp;
a[i].remain-=tmp;
a[i^1].remain+=tmp;
limit-=tmp;
S[s]=a[i].to;
if(!limit) break;
}
}
return ans;
}
inline int dinic(int s,int t)
{
int ans=0;
while(bfs(s,t)) ans+=dfs(s,t,INF);
return ans;
}
int main()
{
memset(head,-1,sizeof(head));
read(m),read(n);
while(1)
{
read(x),read(y);
if(x==-1&&y==-1) break;
add(x,y);
}

for(int i=1;i<=m;i++)
add(n+1,i);
for(int i=m+1;i<=n;i++)
add(i,n+2);
ans=dinic(n+1,n+2);
if(ans)
{
printf("%d\n",ans);
int tmp=0;
for(int i=1;i<=num;i++)
{
if(S[i]) printf("%d %d\n",i,S[i]),tmp++;
if(tmp==ans) break;
}
}
else printf("No Solution!");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  网络流24题