咳咳……
傳送門:
這個題的基本模型:二分圖最大匹配。。
我們可以將外籍飛行員放在左邊,英國飛行員放在右邊,能合作的兩個飛行員之間連一條邊,構出來的圖就像這樣~~
這樣能派出的最大飛機數就是這個二分圖的最大匹配……
最簡單的演算法是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的邊,每個英國飛行員向能配合的外...