這題是二分圖匹配,題目要求輸出最大的配對數,以及配對方案。
學過網路流之後這題就可以寫了,除了外籍飛行員和英國皇家飛行員之外,我們建立乙個源點-- 0 和匯點-- n+1。
讓源點連線外籍飛行員,建立一條邊流量為1的邊,然後建立反邊。再給英國皇家飛行員連線上匯點,同樣邊的流量為1,反邊流量為0。
這樣的話網路流的圖就建立好了,第一問求的最大匹配數,就是這個圖的最大流。對於配對方案的話,一般的寫法就是便利所有的外籍飛行員,輸出正向邊流量為0的就可以了。
我的寫法比較特殊,因為考慮到我們的流可能存在一條邊被走了兩次,所以,也就是說某個外籍飛行員本身已經匹配過了,但是,另外乙個外籍飛行員進行匹配時,走了原本飛行員的配對方案,所以兩條路徑,一條路徑的長度起碼包括4個點,另一條路徑就是直接的配對方案數。
如果此時直接輸出路徑,肯定就輸出了三條以上的路徑。為了解決這個問題,我們知道,如果有一條邊的長度大於兩個點,另一條路徑的長度等於兩個點,並且這兩條路都走過同一條邊,說明,路徑長的那條路,肯定是後走的,短的路肯定是先走的。
所以我們就從後向前輸出,只輸出匹配方案數條,並且,如果某個外籍飛行員輸出國匹配方案數,我們就不在輸出有關他的匹配方案,因為長路徑可能交叉。
對於長路徑,如果兩個一對輸出的話,其實就是匹配方案,畫個圖觀察一下。
#include
#include
#include
#include
using
namespace std;
const
int maxn=
11000
;const
int inf=
1<<30;
int m,n,ecnt,s,t;
struct edge
;struct node
;edge edge[
2*maxn]
;node pre[maxn]
;bool vis[maxn]
;int head[maxn]
;bool map[
110]
[110];
int road[maxn]
;int rcnt=0;
void
addedge
(int u,
int v,
int w)
void
init()
for(
int i=m+
1;i<=n;i++)}
bool
bfs(
) q.
push
(v);}}
}return
false;}
intek()
}for
(int i=t;i!=s;i=pre[i]
.u) ans+
=mi;
}return ans;
}int
main()
addedge
(u,v,1)
;addedge
(v,u,0)
;//map[u][v]=true;
}int ans=ek(
);printf
("%d\n"
,ans)
;memset
(vis,0,
sizeof
(vis));
for(
int i=rcnt-
1;i>
0;i-=2
)if(!vis[road[i]])
}return0;
}//乙個有用的樣例
//5 10
//3 8
//3 7
//1 7
//-1 -1
洛谷 P2756 飛行員配對方案問題
題目背景 第二次世界大戰時期.題目描述 英國皇家空軍從淪陷國徵募了大量外籍飛行員。由皇家空軍派出的每一架飛機都需要配備在航行技能和語言上能互相配合的2 名飛行員,其中1 名是英國飛行員,另1名是外籍飛行員。在眾多的飛行員中,每一名外籍飛行員都可以與其他若干名英國飛行員很好地配合。如何選擇配對飛行的飛...
洛谷P2756 飛行員配對方案問題
第二次世界大戰時期.英國皇家空軍從淪陷國徵募了大量外籍飛行員。由皇家空軍派出的每一架飛機都需要配備在航行技能和語言上能互相配合的2 名飛行員,其中1 名是英國飛行員,另1名是外籍飛行員。在眾多的飛行員中,每一名外籍飛行員都可以與其他若干名英國飛行員很好地配合。如何選擇配對飛行的飛行員才能使一次派出最...
洛谷 P2756 飛行員配對方案問題
題目背景 第二次世界大戰時期.題目描述 英國皇家空軍從淪陷國徵募了大量外籍飛行員。由皇家空軍派出的每一架飛機都需要配備在航行技能和語言上能互相配合的2 名飛行員,其中1 名是英國飛行員,另1名是外籍飛行員。在眾多的飛行員中,每一名外籍飛行員都可以與其他若干名英國飛行員很好地配合。如何選擇配對飛行的飛...