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

    题目:https://www.luogu.org/problemnew/show/2756

    题目背景

    第二次世界大战时期..

    题目描述

    英国皇家空军从沦陷国征募了大量外籍飞行员。由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的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 

    解析

    网络流24题之一orz。

    二分图最大匹配。

    S和外籍连容量为1的边。

    英籍和T连容量为1的边。

    外籍和英籍能一块的连容量为1的边。

    跑最大流,得最大数量。

    查找连接英籍与外籍飞行员的边。

    如果满流,则输出两人编号。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<queue>
      7 #include<vector>
      8 #define inf 2<<29
      9 #define S 0
     10 #define T 300
     11 using namespace std;
     12 
     13 struct line{
     14     int from,to;
     15     int cap,flow;
     16 };
     17 vector<line> edge;
     18 vector<int> G[330];
     19 
     20 int m,n;
     21 int x,y;
     22 int ans,cnt;
     23 
     24 int vis[330];
     25 int cur[330];
     26 int dis[330];
     27 
     28 void addedge(int from,int to,int cap){
     29     edge.push_back((line){from,to,cap,0});
     30     edge.push_back((line){to,from,0,0});
     31     int m=edge.size();
     32     G[from].push_back(m-2);
     33     G[to].push_back(m-1);
     34 }
     35 
     36 bool bfs(){
     37     memset(vis,0,sizeof(vis));
     38     queue<int> q;
     39     q.push(S);
     40     dis[S]=0;
     41     vis[S]=1;
     42     while (!q.empty()){
     43         int now=q.front();
     44         q.pop();
     45         for (int i=0;i<G[now].size();++i){
     46             line e=edge[G[now][i]];
     47             if (!vis[e.to]&&e.cap>e.flow){
     48                 q.push(e.to);
     49                 vis[e.to]=1;
     50                 dis[e.to]=dis[now]+1;
     51             }
     52         }
     53     }
     54     return vis[T];
     55 }
     56 
     57 int dfs(int x,int a){
     58     if (x==T||a==0) return a;
     59     int f,flow=0;
     60     for (int& i=cur[x];i<G[x].size();++i){
     61         line& e=edge[G[x][i]];
     62         if ((dis[e.to]==dis[x]+1)&&(f=dfs(e.to,min(a,e.cap-e.flow)))){
     63             flow+=f;
     64             a-=f;
     65             e.flow+=f;
     66             edge[G[x][i]^1].flow-=f;
     67             if (!a) break;
     68         }
     69     }
     70     return flow;
     71 }
     72 
     73 void dinic(){
     74     while (bfs()){
     75         memset(cur,0,sizeof(cur));
     76         ans+=dfs(S,inf);
     77     }
     78 }
     79 
     80 int main(){
     81     scanf("%d%d",&m,&n);
     82     for (int i=1;i<=m;++i)
     83       addedge(S,i,1);
     84     for (int i=1;i<=n;++i)
     85       addedge(i+m,T,1);
     86     scanf("%d%d",&x,&y);
     87     while (x!=-1&&y!=-1){
     88         addedge(x,y+m,1);
     89         scanf("%d%d",&x,&y);
     90     }
     91     dinic();
     92     if (ans==0){
     93         printf("No Solution!");
     94         return 0;
     95     }
     96     printf("%d
    ",ans);
     97     
     98     int maxsize=edge.size(); 
     99     
    100     for (int i=0;i<maxsize;i+=2){
    101         if (edge[i].flow==1&&
    102             edge[i].from!=S&&edge[i].to!=T){
    103                 printf("%d %d
    ",edge[i].from,edge[i].to-m);
    104                 ++cnt;
    105                 if (cnt==ans) break;
    106             }
    107     }
    108     return 0;
    109 }
    View Code
     
  • 相关阅读:
    MOSS2007图片库的幻灯片视图在IE8标准渲染模式下的bug及其修正
    分享一个WM上绘制饼图、柱形图、折线图的控件类
    C# 中启动进程的三种方法
    SSCLI 包含了微软的CLI ,C#,JScript....的源码,学习.Net的不看怎么行
    (2)继承关系中的多态性编译时与运行时
    .NET.性能:装箱与拆箱、string stringBuilder、struct class、Add AddRangle等影响性能分析
    .NET.GC学习总结
    .NET.GC 浅谈.net托管程序中的资源释放问题 (转帖)
    (1)通过IL来看构造函数
    conda的使用
  • 原文地址:https://www.cnblogs.com/gjc1124646822/p/8053342.html
Copyright © 2011-2022 走看看