zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    2 数据库开发--MySQL下载(windows)
    Spring课程 Spring入门篇 3-1 Spring bean装配(上)之bean的配置项及作用域
    Spring课程 Spring入门篇 2-2 Spring注入方式
    Spring课程 Spring入门篇 2-1 IOC和bean容器
    maven课程 项目管理利器-maven 5-1 课程总结 1星(2018-11-08 07:19)
    maven课程 项目管理利器-maven 4-1 使用maven创建web项目 5星
    maven课程 项目管理利器-maven 3-10 maven聚合和继承 4星
    maven课程 项目管理利器-maven 3-9 maven依赖冲突 4星
    maven课程 项目管理利器-maven 3-8 maven依赖传递 4星
    maven课程 项目管理利器-maven 3-7 maven依赖范围 2星
  • 原文地址:https://www.cnblogs.com/iboom/p/8779099.html
Copyright © 2011-2022 走看看