1. 程式人生 > >[網絡流24題] 飛行員配對方案問題

[網絡流24題] 飛行員配對方案問題

scrip head size you 博客 pre san sin 一個

題目

Description

英國皇家空軍從淪陷國征募了大量外籍飛行員。由皇家空軍派出的每一架飛機都需要配備在航行技能和語言上能互相配合的2 名飛行員,其中1 名是英國飛行員,另1名是外籍飛行員。在眾多的飛行員中,每一名外籍飛行員都可以與其他若幹名英國飛行員很好地配合。如何選擇配對飛行的飛行員才能使一次派出最多的飛機。對於給定的外籍飛行員與英國飛行員的配合情況,試設計一個算法找出最佳飛行員配對方案,使皇家空軍一次能派出最多的飛機。

對於給定的外籍飛行員與英國飛行員的配合情況,編程找出一個最佳飛行員配對方案,使皇家空軍一次能派出最多的飛機。

Input & Range

第 1 行有 2 個正整數 m 和 n。n 是皇家空軍的飛行員總數(n<100);m 是外籍飛行員數(m<=n)。外籍飛行員編號為 1~m;英國飛行員編號為 m+1~n。

接下來每行有 2 個正整數 i 和 j,表示外籍飛行員 i 可以和英國飛行員 j 配合。最後以 2個-1 結束。

Output

第 1 行是最佳飛行員配對方案一次能派出的最多的飛機數 M。接下來 M 行是最佳飛行員配對方案。每行有 2個正整數 i 和 j,表示在最佳飛行員配對方案中,飛行員 i 和飛行員 j 配對。如果所求的最佳飛行員配對方案不存在,則輸出‘No Solution!’。

Solution

比較裸的最大匹配

匈牙利跑一遍即可,寫博客也是為了加深印象

Code

// By YoungNeal
#include<cstdio>
#include<cstring>
using
namespace std; int m,n,cnt,ans; int head[105]; bool vis[105]; int pre[105]; struct Edge{ int to,nxt; }edge[10005]; void add(int x,int y){ edge[++cnt].to=y; edge[cnt].nxt=head[x]; head[x]=cnt; } bool dfs(int now){ if(vis[now]) return 0; vis[now]=1; for(int i=head[now];i;i=edge[i].nxt){
if(!pre[edge[i].to]||dfs(pre[edge[i].to])){ pre[edge[i].to]=now; return 1; } } return 0; } signed main(){ scanf("%d%d",&m,&n); int x,y; while(scanf("%d%d",&x,&y)){ if(x+y==-2) break; add(y,x); } for(int i=m+1;i<=n;i++){ memset(vis,0,sizeof vis); if(dfs(i)) ans++; } printf("%d\n",ans); for(int i=1;i<=m;i++){ if(pre[i]) printf("%d %d\n",i,pre[i]); } return 0; }

[網絡流24題] 飛行員配對方案問題