[COGS 0014][网络流24题] 搭配飞行员

先贴题面

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

时间: 2024-08-02 02:49:01

[COGS 0014][网络流24题] 搭配飞行员的相关文章

COGS 14. [网络流24题] 搭配飞行员

14. [网络流24题] 搭配飞行员 建边的时候要先从源点向主飞行员和从副飞行员向汇点连边 输入的时候只在两人之间连边 1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 #define maxn 10000 5 #define inf 100000000 6 int n,m,src,dec,cur[maxn],ans,lev[maxn]; 7 int front[maxn],head,tail,que

[网络流24题] 搭配飞行员

14. [网络流24题] 搭配飞行员 ★★☆   输入文件:flyer.in   输出文件:flyer.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾驶员.由于种种原因,例如相互配合的问题,有些驾驶员不能在同一架飞机上飞行,问如何搭配驾驶员才能使出航的飞机最多. 如图,假设有10个驾驶员,如图中的V1,V2,…,V10就代表达10个驾驶员,其中V1,V2,

14. [网络流24题] 搭配飞行员

14. [网络流24题] 搭配飞行员 ★★☆   输入文件:flyer.in   输出文件:flyer.out   简单对比 时间限制:1 s   内存限制:128 MB [问题描述] 飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾驶员.由于种种原因,例如相互配合的问题,有些驾驶员不能在同一架飞机上飞行,问如何搭配驾驶员才能使出航的飞机最多. 如图,假设有10个驾驶员,如图中的V1,V2,…,V10就代表达10个驾驶员,其中V1,V2

COGS——C 14. [网络流24题] 搭配飞行员

http://cogs.pro/cogs/problem/problem.php?pid=14 ★★☆   输入文件:flyer.in   输出文件:flyer.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾驶员.由于种种原因,例如相互配合的问题,有些驾驶员不能在同一架飞机上飞行,问如何搭配驾驶员才能使出航的飞机最多. 如图,假设有10个驾驶员,如图中的V

COGS14. [网络流24题] 搭配飞行员

[问题描述] 飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾驶员.由于种种原因,例如相互配合的问题,有些驾驶员不能在同一架飞机上飞行,问如何搭配驾驶员才能使出航的飞机最多. 如图,假设有10个驾驶员,如图中的V1,V2,…,V10就代表达10个驾驶员,其中V1,V2,V3,V4,V5是正驾驶员,V6,V7,V8,V9,V10是副驾驶员.如果一个正驾驶员和一个副驾驶员可以同机飞行,就在代表他们两个之间连一条线,两个人不能同机飞行,就不连

【COGS 14】 [网络流24题] 搭配飞行员 网络流板子题

用网络流水二分图的模型(存一下板子) #include <cstdio> #include <cstring> #include <algorithm> #define N 105 #define R register #define inf 0x7f7f7f7f using namespace std; inline int read() { R int sum=0; R char ch=getchar(); while(ch<'0'||ch>'9')ch

【网络流24题】飞行员配对方案问题

[网络流24题]飞行员配对方案问题 题面 这些题都用Cogs交算了 因为cogs有SPJ 题面 题解 很简单的二分图匹配 匈牙利算法就能够解决 求最大流的话 再加上一个源点一个汇点即可 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set>

dinic求解二分图最大匹配&amp;&amp;网络流24题之飞行员配对方案问题

在二分图的基础上增加源S和汇T.1.S向X集合中每个顶点连一条容量为1的有向边.2.Y集合中每个顶点向T连一条容量为1的有向边.3.XY集合之间的边都设为从A集合中的点到B集合之中的点,容量为1的有向边. 求网络最大流,流量就是匹配数,所有满流边是一组可行解. 所以就解决了. 飞行员配对方案问题: 题目背景 第二次世界大战时期.. 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其中1 名是英国飞行员,另1名是外

「网络流24题」飞行员配对方案问题

传送门:>Here< 题意:二分图匹配输出方案 思路分析 学会了最大流再也不用敲匈牙利了哈哈…… 最大流可以直接解决二分图匹配问题,方法是:将左侧节点与右侧节点的无向边全都变为容量为1的弧(正反),源点一一连向左侧节点,右侧节点一一连向汇点.跑最大流即可 关于为什么这样做是正确的,可以参见算法导论中有严格的证明.但其实这是一目了然的,由于所有弧的容量都为1,从源点连向左侧节点也就意味着最多只有1的流量到达每个节点.这个1就代表了这个节点只能被匹配一次.而右侧节点到汇点的容量也是1,意味着右侧节