題目描述
問題描述:
第二次世界大戰時期,英國皇家空軍從淪陷國徵募了大量外籍飛行員。由皇家空軍派出的每一架飛機都需要配備在航行技能和語言上能互相配合的2名飛行員,其中1名是英國飛行員,另1名是外籍飛行員。在眾多的飛行員中,每一名外籍飛行員都可以與其他若干名英國飛行員很好地配合。如何選擇配對飛行的飛行員才能使一次派出最多的飛機。對於給定的外籍飛行員與英國飛行員的配合情況,試設計乙個演算法找出最佳飛行員配對方案,使皇家空軍一次能派出最多的飛機。
程式設計任務:
對於給定的外籍飛行員與英國飛行員的配合情況,程式設計找出乙個最佳飛行員配對方案,使皇家空軍一次能派出最多的飛機。
輸入格式
2205.in
檔案第1行有2個正整數m和n。n是皇家空軍的飛行員總數(n<100);m是外籍飛行員數。外籍飛行員編號為1~m;英國飛行員編號為m+1~n。
接下來每行有2個正整數i 和j,表示外籍飛行員i 可以和英國飛行員j配合。檔案最後以2個-1結束。
輸出格式
2205.out
第1行是最佳飛行員配對方案一次能派出的最多的飛機數m。
這題是經典的二分圖最大匹配問題。 [
設g=(v,e)是乙個無向圖,如果頂點v可分割為兩個互不相交的子集(a,b),並且圖中的每條邊(i,j)所關聯的兩個頂點i和j分別屬於這兩個不同的頂點集(iin a,j in b),則稱圖g為乙個二分圖]
我們可以將原題的英國飛行員和外籍飛行員都抽象為圖中的結點。可以這樣構圖:
外籍飛行員屬於a集合,英國飛行員屬於b集合。在原圖中增加源點s和匯點t。
s向a集合中每個頂點連一條容量為1的有向邊。
a、b集合之間的邊都設為從a集合中的點到b集合之中的點,容量為1的有向邊。
y集合中每個頂點向t連一條容量為1的有向邊。
(當然,反向邊也是必須建的) 即:
然後,在原圖上跑一遍最大流,最大流即為最大匹配數。x,y之間的滿流邊就是一組可行解。
為什麼這樣構圖?為什麼這樣做即是答案?
我們需要構造這樣乙個圖,使得若干對飛行員匹配成功之後,出發的外籍(英國)飛行員盡可能多。而這恰好就是最大流的具體體現。
我們只在可以匹配的飛行員之間連邊,使得當且僅當能夠匹配時,才有可能是可行的方案。每對飛行員之間邊的權值為inf。
由於每對飛行員只能飛一架飛機,飛行員只能一一匹配,因而從源點s連出的邊權值為1,從b到匯點t的邊權值也為1。
這樣做,每個流只能為1,它的意義為:有一駕飛機能夠出發。跑出的最大流,自然就是最多的飛機數量。
其實,對於二分圖最大匹配圖,構圖的關鍵可能就是,增加源點s和匯點t,使得流為合法解,且保證匹配是一一對應的。總之,必須要清楚每個流的意義,如果它與題目所求相契合,自然是正確的。
**如下:
#include
#include
#include
using namespace std;
const int maxn=205,inf=10000000;
int head[maxn],cur;
int v[maxn*2],m,n,s,t,a,b;
int ans;
struct yy
edge[maxn*maxn];
void add(int from,int to,int va,int type)
void init()
for(int i=1;i<=m;i++)
for(int i=m+1;i<=n;i++)
}int dfs(int cur,int mina)
} h=edge[h].next;
} return 0;
}int main()
if(ans!=0) cout<
<
飛行員配對方案問題
第二次世界大戰時期.英國皇家空軍從淪陷國徵募了大量外籍飛行員。由皇家空軍派出的每一架飛機都需要配備在航行技能和語言上能互相配合的2 名飛行員,其中1 名是英國飛行員,另1名是外籍飛行員。在眾多的飛行員中,每一名外籍飛行員都可以與其他若干名英國飛行員很好地配合。如何選擇配對飛行的飛行員才能使一次派出最...
飛行員配對方案
題目大意 只要外籍飛行員與英籍飛行員匹配就可以駕駛一架飛機,共有n個飛行員,其中有m個外籍的,問最多有多少對匹配的飛行員 乙個外籍乙個英籍 解題思路 方法 網路流 最大流 匈牙利演算法 這裡用網路流 最大流 首先建乙個源點和乙個匯點,源點與外籍飛行員間建立一條有向邊 外籍飛行員方向 匯點與英籍飛行員...
網路流 飛行員配對方案問題
題目描述 第二次世界大戰時期,英國皇家空軍從淪陷國徵募了大量外籍飛行員。由皇家空軍派出的每一架飛機都需要配備在航行技能和語言上能互相配合的2 名飛行員,其中1 名是英國飛行員,另1名是外籍飛行員。在眾多的飛行員中,每一名外籍飛行員都可以與其他若干名英國飛行員很好地配合。如何選擇配對飛行的飛行員才能使...