zoukankan      html  css  js  c++  java
  • 洛谷P2756 飞行员配对方案问题

    原题传送门

    题目背景

    第二次世界大战时期..

    题目描述

    英国皇家空军从沦陷国征募了大量外籍飞行员。由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其中1 名是英国飞行员,另1名是外籍飞行员。在众多的飞行员中,每一名外籍飞行员都可以与其他若干名英国飞行员很好地配合。如何选择配对飞行的飞行员才能使一次派出最多的飞机。对于给定的外籍飞行员与英国飞行员的配合情况,试设计一个算法找出最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。

    对于给定的外籍飞行员与英国飞行员的配合情况,编程找出一个最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。

    输入输出格式

    输入格式:

    第 1 行有 2 个正整数 m 和 n。n 是皇家空军的飞行员总数(n<100);m 是外籍飞行员数(m<=n)。外籍飞行员编号为 1~m;英国飞行员编号为 m+1~n。

    接下来每行有 2 个正整数 i 和 j,表示外籍飞行员 i 可以和英国飞行员 j 配合。最后以 2个-1 结束。

    输出格式:

    第 1 行是最佳飞行员配对方案一次能派出的最多的飞机数 M。接下来 M 行是最佳飞行员配对方案。每行有 2个正整数 i 和 j,表示在最佳飞行员配对方案中,飞行员 i 和飞行员 j 配对。如果所求的最佳飞行员配对方案不存在,则输出‘No Solution!’。

    输入输出样例

    输入样例#1: 复制
    5 10
    1 7
    1 8
    2 6
    2 9
    2 10
    3 7
    3 8
    4 7
    4 8
    5 10
    -1 -1
    输出样例#1: 复制
    4
    1 7
    2 9
    3 8
    5 10

    题解

    前置知识二分图

    这道题思维难度不高,代码比较套路,题面已经透露了算法:二分图匹配

    我们只需要将英国飞行员作为左集合中的元素,将外籍飞行员作为右集合的元素,每一种匹配方案连一条边,然后用最大流匹配算法就能解决此题。

    关键在于输出方案,匈牙利算法和网络流算法输出方案的方法不同

    匈牙利算法

    匈牙利算法在过程中就留下了天然的配对数组(match数组),直接输出即可

    网络流算法(此处是Dinic)

    网络流算法没有天然的配对关系,但我们只要记录每一个点将流量流向了哪一个点,依次输出即可

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int MAXN=1e3+7,MAXM=1e6+7,INF=1e9+7;
      4 int N,M,S,T;
      5 int to[MAXM*2],nxt[MAXM*2],head[MAXM*2],val[MAXM*2],tp=1;
      6 inline void add(int x,int y,int z){
      7     nxt[++tp]=head[x];
      8     head[x]=tp;
      9     val[tp]=z;
     10     to[tp]=y;
     11 }
     12 int de[MAXN],gap[MAXN];
     13 inline void bfs(){
     14     queue<int> que;
     15     memset(gap,0,sizeof(gap));
     16     memset(de,-1,sizeof(de));
     17     que.push(T);
     18     de[T]=0;
     19     gap[0]=1;
     20     while(que.size()){
     21         int ii=que.front();
     22         que.pop();
     23         for(int i=head[ii];i;i=nxt[i]){
     24             if(de[to[i]]!=-1){
     25                 continue;
     26             }
     27             de[to[i]]=de[ii]+1;
     28             gap[de[to[i]]]++;
     29             que.push(to[i]);
     30         }
     31     }
     32 }
     33 int cur[MAXN],maxflow;
     34 int dfs(int x,int flow){
     35     if(x==T){
     36         maxflow+=flow;
     37         return flow;
     38     }
     39     int used=0;
     40     for(int i=cur[x];i;i=nxt[i]){
     41         cur[x]=i;
     42         if(val[i]&&de[to[i]]+1==de[x]){
     43             int ii=dfs(to[i],min(flow-used,val[i]));
     44             if(ii){
     45                 used+=ii;
     46                 val[i]-=ii;
     47                 val[i^1]+=ii;
     48                 if(used==flow){
     49                     return used;
     50                 }
     51             }
     52         }
     53     }
     54     gap[de[x]]--;
     55     if(!gap[de[x]]){
     56         de[S]=N+3;
     57     }
     58     de[x]++;
     59     gap[de[x]]++;
     60     return used;
     61 }
     62 int main(){
     63     scanf("%d%d",&M,&N);
     64     S=N+1;
     65     T=N+2;
     66     for(int i=1;i<=M;i++){
     67         add(S,i,1);
     68         add(i,S,0);
     69     }
     70     for(int i=M+1;i<=N;i++){
     71         add(i,T,1);
     72         add(T,i,0);
     73     }
     74     while(1){
     75         int ii,jj;
     76         scanf("%d%d",&ii,&jj);
     77         if(ii==-1&&jj==-1){
     78             break;
     79         }
     80         add(ii,jj,1);
     81         add(jj,ii,0);
     82     }
     83     bfs();
     84     while(de[S]<N+2){
     85         memcpy(cur,head,sizeof(cur));
     86         dfs(S,INF);
     87     }
     88     if(!maxflow){
     89         printf("No Solution!");
     90     }else{
     91         printf("%d
    ",maxflow);
     92         for(int i=1;i<=M;i++){
     93             for(int j=head[i];j;j=nxt[j]){
     94                 if(to[j]!=T&&to[j]!=S&&val[j^1]){
     95                     printf("%d %d
    ",i,to[j]);
     96                 }
     97             }
     98         }
     99     }
    100     return 0;
    101 }
  • 相关阅读:
    Atitti 图像处理 图像混合 图像叠加 blend 原理与实现
    Atitit Gaussian Blur 高斯模糊 的原理and实现and 用途
    Atitit 图像处理 灰度图片 灰度化的原理与实现
    Atitit (Sketch Filter)素描滤镜的实现  图像处理  attilax总结
    Atitit 实现java的linq 以及与stream api的比较
    Atitit attilax在自然语言处理领域的成果
    Atitit 图像处理 常用8大滤镜效果 Jhlabs 图像处理类库 java常用图像处理类库
    Atitit 图像处理--图像分类 模式识别 肤色检测识别原理 与attilax的实践总结
    Atitit apache 和guava的反射工具
    atitit。企业的价值观 员工第一 vs 客户第一.docx
  • 原文地址:https://www.cnblogs.com/guoshaoyang/p/10567230.html
Copyright © 2011-2022 走看看