• P2756 网络流解决二分图最大匹配


     

    P2756 飞行员配对方案问题

    题目背景

    第二次世界大战时期..

    题目描述

    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: 复制
    3
    4 2 1
    2 3 2
    1
    2 3 2 1 2
    输出样例#1: 复制
    11

    说明

    样例解释

    A耕地种1,2,B耕地种3,收益4+2+3+2=11。

    数据范围与约定

    1<=k< n<= 1000,0 < m < = 1000 保证所有数据及结果不超过2*10^9。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<vector>
      5 #include<queue>
      6 #include<cstdio>
      7 #define maxn 10005
      8 #define maxm 100005
      9 #define inf 200000000
     10 using namespace std;
     11 struct edge{
     12     int from;
     13     int to;
     14     int flow;
     15     int cap;
     16 };
     17 int cur[maxn],d[maxn];
     18 bool vis [maxn];
     19 int m=0,n,a,b,c,k,s,t;
     20 vector <int> g[maxn];
     21 vector <edge> edges;
     22 void add_edge(int a,int b,int c)
     23 {
     24     m+=2;
     25     edges.push_back({a,b,0,c});
     26     edges.push_back({b,a,0,0});
     27     g[b].push_back(m-1);
     28     g[a].push_back(m-2);
     29 }
     30 bool BFS()
     31 {
     32     
     33     //cout<<"bfs"<<"   1   "<<endl;
     34     memset(vis,0,sizeof(vis));
     35     queue <int> q;
     36     q.push(s);
     37     d[s]=0;
     38     vis[s]=1;
     39     while(! q.empty())
     40     {
     41         
     42         int u=q.front();q.pop();
     43         for(int i=0;i<g[u].size();i++)
     44         {
     45             if(!vis[edges[g[u][i]].to]&&edges[g[u][i]].cap>edges[g[u][i]].flow)
     46             {    
     47                 d[edges[g[u][i]].to]=d[u]+1;
     48                 vis[edges[g[u][i]].to]=1;
     49                 
     50                 q.push(edges[g[u][i]].to);
     51             }
     52         }
     53     }
     54     return vis[t];
     55 }
     56 long long dfs(int x,int a)
     57 {
     58     if (x==t || a==0) return a;
     59     long long flow=0;int f;
     60     for(int &i=cur[x]; i< g[x].size(); i++)
     61     {
     62         if (d[x]+1==d[edges[g[x][i]].to] && (f=dfs(edges[g[x][i]].to,min(a,edges[g[x][i]].cap-edges[g[x][i]].flow)))>0)
     63         {
     64             edges[g[x][i]].flow+=f;
     65             edges[g[x][i]^1].flow-=f;
     66             flow+=(long long)1*f;
     67             a-=f;
     68             if (a==0) break;
     69         }
     70     }
     71     return flow;
     72     
     73 }
     74 int maxflow(int s,int t)
     75 {
     76     long long flow=0;
     77     while(BFS()==1)
     78     {
     79         memset(cur,0,sizeof(cur));
     80         flow+=(long long)dfs(s,inf);
     81     }
     82     return flow;
     83 }
     84 int main()
     85 {
     86     cin>>n>>k;
     87     s=0;t=k+1;c=0;
     88     for(int i=1;i<=n;i++)
     89     {
     90         add_edge(s,i,1);
     91     }
     92     for(int i=n+1;i<=k;i++)
     93     {
     94         add_edge(i,t,1);
     95     }
     96     cin>>a>>b;
     97     while(a!=-1)
     98     {    
     99         c++;
    100         add_edge(a,b,1);
    101         cin>>a>>b;
    102     }
    103     int flow=maxflow(s,t);
    104     if(!flow) printf("No answer\n");
    105     else{
    106         printf("%d\n",flow);
    107         for(int i=1;i<=n;i++)
    108             for(int j=0;j<g[i].size();j++) 
    109                 if(edges[g[i][j]].cap==1 &&edges[g[i][j]].flow==1) printf("%d %d\n",i,edges[g[i][j]].to);
    110                 //如果这条边是满的并且不为反向边,说明这两个点是匹配的
    111     }
    112 
    113     return 0;
    114 }
  • 相关阅读:
    如何实现Echart不刷新页面,多语言切换下的地图数据重新加载,api请求数据加载,soketed数据实时加载
    web开发中各种宽高
    http请求方式和传递数据类型
    Hexo之傻瓜攻略
    SQL2008 R2安装功能选择
    Windows Server2012 R2中安装SQL Server2008
    用户权限管理数据库设计
    C#生成缩略图 (通用模式)
    CAD习题集
    菜鸟学习MVC实录:弄清项目各类库的作用和用法
  • 原文地址:https://www.cnblogs.com/iboom/p/8779099.html
Copyright © 2020-2023  润新知