A、飞行员配对方案问题 (二分图最大匹配)(最大流)【提高+/省选- 】

题目链接


【问题分析】

二分图最大匹配问题。

【建模方法】

在二分图的基础上增加源S和汇T。 1、S向X集合中每个顶点连一条容量为1的有向边。 2、Y集合中每个顶点向T连一条容量为1的有向边。 3、XY集合之间的边都设为从A集合中的点到B集合之中的点,容量为1的有向边。

  • 节点
源点:0
外国人:1->m
本国人:m+1->n
汇点:n+1
(源点,外国人,1)
(外国人,本国人,INF)
(本国人,汇点,1)

求网络最大流,流量就是匹配数,所有满流边是一组可行解。

【建模分析】

基本的二分图最大匹配,可以直接用匈牙利算法或Hopcroft_Karp算法解决,更一般的方法是网络最大流。

求出的最大流即为最多的匹配对数。

要得到匹配方案,既是判断各边是否有流量,即判断反向边的权值是否不为0。
有流量的边即为要输出的匹配对。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<math.h>
#include<cstring>
#include<queue>
//#define ls (p<<1)
//#define rs (p<<1|1)
#define over(i,s,t) for(register int i = s;i <= t;++i)
#define lver(i,t,s) for(register int i = t;i >= s;--i)
//#define int __int128
//#define lowbit(p) p&(-p)
using namespace std;typedef long long ll;
typedef pair<int,int> PII;
const int INF = 0x3f3f3f3f;
const int N = 5e2+7;
const int M = 2e5+7;int head[N],nex[M],ver[M],tot = 1;
int edge[M];
int n,m,s,t;
int maxflow;
int deep[N];//层级数,其实应该是level
int now[M];//当前弧优化
queue<int>q;inline void read(int &x){int f=0;x=0;char c=getchar();while(c<'0'||c>'9')f|=c=='-',c=getchar();while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();x=f?-x:x;
}inline void add(int x,int y,int z){//建正边和反向边ver[++tot] = y;edge[tot] = z;nex[tot] = head[x];head[x] = tot;ver[++tot] = x;edge[tot] = 0;nex[tot] = head[y];head[y] = tot;
}inline bool bfs(){//在残量网络中构造分层图memset(deep,0x3f,sizeof deep);while(!q.empty())q.pop();q.push(s);deep[s] = 0;now[s] = head[s];//一些初始化while(!q.empty()){int x = q.front();q.pop();for(int i = head[x];i;i = nex[i]){int y = ver[i];if(edge[i] > 0 && deep[y] == INF){//没走过且剩余容量大于0q.push(y);now[y] = head[y];//先初始化,暂时都一样deep[y] = deep[x] + 1;if(y == t)return 1;//找到了}}}return 0;
}//flow是整条增广路对最大流的贡献,rest是当前最小剩余容量,用rest去更新flow
ll dfs(int x,int flow){//在当前分层图上增广if(x == t)return flow;int ans = 0,k,i;for(i = now[x];i && flow;i = nex[i]){now[x] = i;//当前弧优化(避免重复遍历从x出发的不可拓展的边)int y = ver[i];if(edge[i] > 0 && (deep[y] == deep[x] + 1)){//必须是下一层并且剩余容量大于0k = dfs(y,min(flow,edge[i]));//取最小if(!k)deep[y] = INF;//剪枝,去掉增广完毕的点edge[i] -= k;//回溯时更新edge[i ^ 1] += k;//成对变换ans += k;flow -= k;}//if(!flow)return rest;}return ans;
}void dinic(){while(bfs())maxflow += dfs(s,INF);
}int tmp1,tmp2;
int main()
{read(m),read(n);s = 0,t = n + 1;while(scanf("%d%d",&tmp1,&tmp2) && (tmp1 != -1 && tmp2 != -1))add(tmp1,tmp2,0x3f3f3f3f);for(int i = 1;i <= m;++i)add(s,i,1);//每一条增广路是一条匹配for(int i = m + 1;i <= n;++i)add(i,t,1);dinic();if(!maxflow){puts("No Solution!");return 0;}cout<<maxflow<<endl;for(int i = 2;i <= tot;i += 2){if(ver[i] != s && ver[i ^ 1] != s)if(ver[i] != t && ver[i ^ 1] != t)if(edge[i ^ 1] != 0)printf("%d %d\n",ver[i ^ 1],ver[i]);}return 0;
}

【网络流24题】解题报告:A、飞行员配对方案问题(最大流求二分图最大匹配)相关推荐

  1. 【网络流24题】No.7 试题库问题 (最大流,二分图多重匹配)

    [题意] 假设一个试题库中有 n 道试题. 每道试题都标明了所属类别. 同一道题可能有多个类别属性.现要从题库中抽取 m 道题组成试卷.并要求试卷包含指定类型的试题. 试设计一个 满足要求的组卷算法. ...

  2. 【网络流24题】餐巾计划问题(最小费用最大流)

    [网络流24题]餐巾计划问题(最小费用最大流) 题面 COGS 洛谷上的数据范围更大,而且要开longlong 题解 餐巾的来源分为两种: ①新买的 ②旧的拿去洗 所以,两种情况分别建图 先考虑第一种 ...

  3. LuoguP2756 飞行员配对方案问题(最大流)

    题目背景 第二次世界大战时期.. 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其中1 名是英国飞行员,另1名是外 ...

  4. 【网络流24题】【LOJ6010】数字梯形(费用流)

    problem 给定一个n行的数字梯形,第一行有m个数字 从第一行的每个数字开始往左下或右下移动到底,累加路径上的值 求数字总和最大. 满足限制: 1.路径互不相交 2.路径仅在数字结点处相交 3.路 ...

  5. 解题报告:线性规划与网络流24题

    目录 A.飞行员配对方案问题 (二分图最大匹配)(最大流)[提高+/省选- ] B.太空飞行计划问题(最大权闭合图转最小割.最小割方案输出)[省选/NOI- ] C.最小路径覆盖问题(有向无环图最小路 ...

  6. [线性规划与网络流24题] 网络流常见模型

    最近两个月在做<线性规划与网络流24题>这套题,加深了对网络流的理解. 涵盖到的模型有:二分图匹配.二分图的最大独立集.最大权闭合图.有向无环图的最小路径覆盖.最多不相交路径.最大权不相交 ...

  7. 网络流24题 飞行员配对方案问题

    «问题描述: 第二次世界大战时期,英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出 的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其中1 名是英国飞 行员,另1 名是外籍飞 ...

  8. P2756 飞行员配对方案问题【网络流24题】

    P2756 飞行员配对方案问题 文章目录 题目背景 题解: 代码: 题目背景 第二次世界大战期间,英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相 ...

  9. 网络流24题-飞行员配对方案问题

    飞行员配对方案问题 时空限制1000ms / 128MB 题目背景 第二次世界大战时期.. 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能 ...

最新文章

  1. Pat乙级 1045 快速排序
  2. 特征检测器 FeatureDetector
  3. 2.Redis数据库(搭建redis主从的必要性)以及主从搭建(Windows为例)
  4. 参加腾讯DevDays是一种什么样的感受?
  5. SpringBoot使用日志
  6. Linux 命令之 pwck -- 用来验证系统认证文件内容和格式的完整性
  7. 华鑫证券王习平:让投资变成一件容易事、有趣事
  8. 三款IE修复软件横向评测(转)
  9. 科技热点周刊|马斯克卖掉特斯拉 10% 股票;Facebook 停用面部识别系统;微软拥抱 Metaverse;雅虎退出中国
  10. Dungeon Master(地下城主)
  11. 【图像分类】基于PyTorch搭建LSTM实现MNIST手写数字体识别(单向LSTM,附完整代码和数据集)
  12. 玉湖冷链黄铮洪出任广东省物流标准化技术委员会副主任
  13. 一款简单的声控报警电路
  14. MySQL 更改root密码
  15. 三角形边长求高的c语言函数公式,c 求,已知三角形三边边长为abc,利用公式求面积...
  16. MySQL—运算符详解(算术、比较、逻辑、范围运算符与集合运算符 模糊查询 NULL值运算与null值判断 位运算符)
  17. 黑客每小时发送3万封性勒索邮件:轻松月入11万!
  18. extjs 4.1 用户管理界面设计
  19. 基于egret引擎、P2物理库的搭积木游戏
  20. 计算机交互式登录进程初始化失败,提示交互式登录进程初始化失败怎么办?

热门文章

  1. 【OpenCV 4开发详解】形态学应用
  2. spring cloud互联网分布式微服务云平台规划分析--服务统一配置中心
  3. Visual Studio 15.8 Preview 3支持多点编辑功能
  4. Linux编程_Shell脚本练习题
  5. DNS解析过程详解【转】
  6. oracle 监听服务自动停止与无法启动问题
  7. tomcat 初始管理用户和密码
  8. android地图定位
  9. 编辑神器VIM下安装zencoding
  10. Something needs to be forgotten.