1. 程式人生 > >[COGS 0014][網絡流24題] 搭配飛行員

[COGS 0014][網絡流24題] 搭配飛行員

dfs cstring mas als 其中 sizeof align 10個 超級

先貼題面

14. [網絡流24題] 搭配飛行員

★★☆ 輸入文件:flyer.in 輸出文件:flyer.out簡單對比
時間限制:1 s 內存限制:128 MB

【問題描述】 飛行大隊有若幹個來自各地的駕駛員,專門駕駛一種型號的飛機,這種飛機每架有兩個駕駛員,需一個正駕駛員和一個副駕駛員。由於種種原因,例如相互配合的問題,有些駕駛員不能在同一架飛機上飛行,問如何搭配駕駛員才能使出航的飛機最多。 技術分享 如圖,假設有10個駕駛員,如圖中的V1,V2,…,V10就代表達10個駕駛員,其中V1,V2,V3,V4,V5是正駕駛員,V6,V7,V8,V9,V10是副駕駛員。如果一個正駕駛員和一個副駕駛員可以同機飛行,就在代表他們兩個之間連一條線,兩個人不能同機飛行,就不連。例如V1和V7可以同機飛行,而V1和V8就不行。請搭配飛行員,使出航的飛機最多。註意:因為駕駛工作分工嚴格,兩個正駕駛員或兩個副駕駛員都不能同機飛行. 【輸入格式】 輸入文件有若幹行
第一行,兩個整數n與n1,表示共有n個飛行員(2<=n<=100),其中有n1名飛行員是正駕駛員.
下面有若幹行,每行有2個數字a,b。表示正駕駛員a和副駕駛員b可以同機飛行。 註:正駕駛員的編號在前,即正駕駛員的編號小於副駕駛員的編號. 【輸出格式】 輸出文件有一行
第一行,1個整數,表示最大起飛的飛機數。 【輸入輸出樣例】 輸入文件名: flyer.in 10 5
1 7
2 6
2 10
3 7
4 8
5 9 輸出文件名:flyer.out 4
講真確實是水題w簡單的二分圖最大匹配,可以轉化為網絡流來做. 首先建立超級源點$s$和$t$(編號$0$和$v+1$),從超級源點向所有正飛行員連一條容量為1的邊,然後對於所有可能的匹配連一條從正飛行員到副飛行員的邊,最後將所有副飛行員連接到超級匯點再跑一遍最大流就得了... 過於蒟蒻的我居然腦抽一開始覺得超級源點和超級匯點要連容量為INF的邊... 好了代碼時間 GitHub 技術分享
  1 #include <queue>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <iostream>
  6 #include <algorithm>
  7 
  8 const int MAXE=10010;
  9 const int MAXV=110;
 10 const int INF=0x7FFFFFFF;
 11 
 12 struct Edge{
 13     int
from; 14 int to; 15 int flow; 16 Edge* rev; 17 Edge* next; 18 }; 19 Edge E[MAXE]; 20 Edge* head[MAXV]; 21 Edge* top=E; 22 23 int v,n; 24 int depth[MAXV]; 25 26 bool BFS(int,int); 27 int Dinic(int,int); 28 int DFS(int,int,int); 29 void Insert(int,int,int); 30 31 int main(){ 32 freopen("flyer.in","r",stdin); 33 freopen("flyer.out","w",stdout); 34 int a,b; 35 scanf("%d%d",&v,&n); 36 while(scanf("%d%d",&a,&b)==2){ 37 Insert(a,b,1); 38 } 39 for(int i=1;i<=n;i++){ 40 Insert(0,i,1); 41 } 42 for(int i=n+1;i<=v;i++){ 43 Insert(i,v+1,1); 44 } 45 printf("%d\n",Dinic(0,v+1)); 46 return 0; 47 } 48 49 int Dinic(int s,int t){ 50 int ans=0; 51 while(BFS(s,t)){ 52 ans+=DFS(s,INF,t); 53 } 54 return ans; 55 } 56 57 inline void Insert(int a,int b,int f){ 58 top->from=a; 59 top->to=b; 60 top->flow=f; 61 top->rev=top+1; 62 top->next=head[a]; 63 head[a]=top; 64 top++; 65 top->from=b; 66 top->to=a; 67 top->flow=0; 68 top->rev=top-1; 69 top->next=head[b]; 70 head[b]=top; 71 top++; 72 } 73 74 bool BFS(int s,int t){ 75 std::queue<int> q; 76 memset(depth,0,sizeof(depth)); 77 depth[s]=1; 78 q.push(s); 79 while(!q.empty()){ 80 int top=q.front(); 81 q.pop(); 82 for(Edge* i=head[top];i!=NULL;i=i->next){ 83 if(depth[i->to]==0&&i->flow!=0){ 84 q.push(i->to); 85 depth[i->to]=depth[top]+1; 86 if(i->to==t) 87 return true; 88 } 89 } 90 } 91 return false; 92 } 93 94 int DFS(int root,int flow,int t){ 95 if(root==t||flow==0) 96 return flow; 97 int tmp=flow; 98 int k; 99 for(Edge* i=head[root];i!=NULL;i=i->next){ 100 if(i->flow!=0&&tmp!=0&&depth[i->to]==depth[root]+1){ 101 k=DFS(i->to,std::min(tmp,i->flow),t); 102 if(k==0){ 103 depth[i->to]=0; 104 continue; 105 } 106 i->flow-=k; 107 i->rev->flow+=k; 108 tmp-=k; 109 if(tmp==0) 110 break; 111 } 112 } 113 return flow-tmp; 114 }
Backup

以及圖包w

技術分享

[COGS 0014][網絡流24題] 搭配飛行員