zoukankan      html  css  js  c++  java
  • [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的边...
    好了代码时间
      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
    ",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 

  • 相关阅读:
    linux_进程管理
    Linux-日志管理
    Httpd
    Linux-源码安装包管理
    Linux-计划任务管理
    Linux-LVM管理
    Linux-系统磁盘管理
    Linux-yum工具的使用
    Linux-rpm包管理
    Linux-网络进阶管理
  • 原文地址:https://www.cnblogs.com/rvalue/p/7257186.html
Copyright © 2011-2022 走看看