學術篇 網路流24題 飛行員配對方案問題

2021-07-27 19:21:47 字數 3188 閱讀 2209

咳咳……

傳送門:

這個題的基本模型:二分圖最大匹配。。

我們可以將外籍飛行員放在左邊,英國飛行員放在右邊,能合作的兩個飛行員之間連一條邊,構出來的圖就像這樣~~

這樣能派出的最大飛機數就是這個二分圖的最大匹配……

最簡單的演算法是hungary algorithm(匈牙利演算法)(並不是hungry)

匈牙利演算法比較簡單,你們自己去搜一下,原理**都很清楚。。

不過令我吐槽的是搜到的模板基本都是鄰接矩陣寫的,而我比較習慣陣列模擬的鄰接表 _ (:з」∠) _

然後下面是**(時間複雜度:o(n^2*m))

#include 

#include

#define gc getchar()

#define cl(a,b) memset(a,b,sizeof(a))

const

int n=505;

struct edgee[n*n+15]; int v[n],tot=1;

int c[n],match[n];

bool vis[n];

int n,m;

inline

int gnum()

void build(int x,int y)

bool dfs(int x)}}

return0;}

int hungary()

int main()while(1);

int ans=hungary();

if(!ans)

printf("%d\n",ans);

for(int i=1;i<=m;i++) //輸出方案..

if(~c[i])

printf("%d %d\n",i,c[i]);

}

不過,二分圖上還n^2*m的演算法怎能忍受..

所以,兩位歪果大神yy出了一種o(n^0.5*m)的演算法..

他們乙個人叫john e. hopcroft,另乙個叫richard m. karp,所以這個演算法叫hopcroft-karp演算法..

這個演算法網上講的也不少,但模板似乎竟然還有假的..(比如這題樣例都會找錯)

還有神犇想要具體研究這個演算法可以去看原始** 其實是可以下到的~~

**你們可以去 下嘛..

**:

#include 

#include

#include

using

std::queue;

#define gc getchar()

#define cl(a,b) memset(a,b,sizeof(a))

const

int n=505;

const

int inf=~0u>>1;

int cx[n],cy[n],dx[n],dy[n];

bool vis[n];

int n,m,dis;

struct nodee[n*n+15]; int v[n],tot=1;

inline

int gnum()

inline

void build(int x,int y)

bool bfs()}}

return dis!=inf;

}bool dfs(int x)}}

return0;}

int hopcroft_karp()

return ans;

}int main()while(1);

int ans=hopcroft_karp();

if(!ans)

printf("%d\n",ans);

for(int i=1;i<=m;i++)

if(~cx[i])printf("%d %d\n",i,cx[i]);

}

這樣就結束了嗎?並不是的,這題還有更一般的做法——網路流。。

不然幹嘛要歸到網路流24題裡啊

我們搞出乙個源點s和匯點t,將所有外籍飛行員與s連邊,將所有英國飛行員與t連邊,

我們再看:

這就是乙個網路流圖了。。

因為是二分圖,我們不妨跑dinic(其實還是o(n^0.5*m))

不過擁有更好的普適性而且還能直接複製貼上板子

**:

#include 

#include

#include

using

std::queue;

using

std::min;

#define gc getchar()

#define cl(a,b) memset(a,b,sizeof(a))

const

int maxv=202;

const

int maxe=40404;

const

int inf=~0u>>1;

struct edgee[maxe]; int v[maxv],tot=1;

int d[maxv];

int cur[maxv];

int s,t;

inline

int gnum()

void build(int x,int y,int z)

bool bfs()

return d[t]>0;

}int dfs(int x,int mx)

}return s;

}int dinic()

void findpath(int m)

int main()while(1);

ans=dinic();

if(!ans) puts("no solution!");

else

printf("%d\n",ans),findpath(m);

}

最後的最後,我要告訴大家乙個秘密^o^:

這題沒有no solutiontion的情況~~

我會說我已經用兩種**a完才看見無解要輸出no solution嘛

the end..

網路流24題 搭配飛行員 飛行員配對方案

網路流24題 搭配飛行員 輸入檔案 flyer.in 輸出檔案 flyer.out 簡單對比 時間限制 1 s 記憶體限制 128 mb 問題描述 飛行大隊有若干個來自各地的駕駛員,專門駕駛一種型號的飛機,這種飛機每架有兩個駕駛員,需乙個正駕駛員和乙個副駕駛員。由於種種原因,例如相互配合的問題,有些...

網路流24題 飛行員配對方案問題

原題目有special judge所以我將題目去掉special judge之後如下 問題描述 第二次世界大戰時期,英國皇家空軍從淪陷國徵募了大量外籍飛行員。由皇家空軍派出 的每一架飛機都需要配備在航行技能和語言上能互相配合的 2 名飛行員,其中 1 名是英國飛 行員,另 1 名是外籍飛行員。在眾多...

網路流24題 飛行員配對方案問題

luogu 2756 給出n個英國飛行員和m個外籍飛行員,給出每個英國飛行員能配合的外籍飛行員編號,求最多可以選出多少對能互相配合的飛行員 最經典的二分圖匹配問題。其實用匈牙利演算法更合適,在時間複雜度上會更加優秀。用網路流來做的話,超級源點向每個英國飛行員連流量為1的邊,每個英國飛行員向能配合的外...