网络流24题-飞行员配对方案问题-二分图最大匹配

这道题,是个人都看得出来,是求一个二分图的最大匹配。

但是网络流24题嘛,我们考虑一下用网络流的方法做。

一般二分图的题,转网络流做,都需要建立一个起点和汇点。然后求一个最大流,这个最大流就是二分图的最大匹配。

我用的是Edmonds-Karp算法bfs版本

代码

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<queue>
using namespace std;
int n,m,s,t,tot,maxflow;
const int inf = 1<<29,N=2010,M=20010;
int head[N],ver[M],edge[M],Next[M],v[N],incf[N],pre[N];
  //邻接表最后一个点(表头),下一个节点,流量,邻接表,数组,增广路上各边最小剩余容量,路径记录
void add(int x,int y,int z){
   ver[++tot]=y,edge[tot]=z,Next[tot]=head[x],head[x]=tot;//正向边
   ver[++tot]=x,edge[tot]=0,Next[tot]=head[y],head[y]=tot;//反向边
}
bool bfs(){
  memset(v,0,sizeof(v));
  queue<int>q;
  q.push(s);
  v[s]=1;
  incf[s]=inf;//增广路上各边最小剩余容量
  while(q.size()){
    int x=q.front();
    q.pop();
    for (int i=head[x];i!=-1;i=Next[i])//开始广度遍历
       if (edge[i]){//流量不为0
          int y=ver[i];
          if(v[y])continue;//这条边在当前的BFS里面已经走过了
          incf[y]=min(incf[x],edge[i]);
          pre[y]=i;//记录前驱,方便把方案保存下来
          q.push(y),v[y]=1;
          if (y==t)return 1;//成功
       }
  }
  return 0;//失败
}
void update(){
  int x=t;
  while(x!=s){
     int i=pre[x];
     edge[i]-=incf[t];//更新流量
     edge[i^1]+=incf[t];//更新反向流量
     x=ver[i^1];
  }
  maxflow+=incf[t];
}
int main(){
  int tmp1,tmp2;
  while(~scanf("%d%d",&m,&n)){
    memset(head,-1,sizeof(head));
    s=0,t=n+1,tot=1,maxflow=0;
    while(1){
        scanf("%d%d",&tmp1,&tmp2);
        if (tmp1==-1 && tmp2==-1)
            break;
        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);
    }
    while(bfs())
        update();
    printf("%d\n",maxflow);
    for (int i=2;i<=tot;i+=2){
        if((ver[i^1]!=s && ver[i]!=t)&&(ver[i]!=s && ver[i^1]!=t))//不能是直接指向起点和汇点的点
        if (edge[i^1]!=0)
        printf("%d %d\n",ver[i^1],ver[i]);
    }
  }
  return 0;
}

留坑匈牙利算法

原文地址:https://www.cnblogs.com/bluefly-hrbust/p/10434865.html

时间: 2024-11-05 04:55:29

网络流24题-飞行员配对方案问题-二分图最大匹配的相关文章

[网络流24题]飞行员配对方案问题

https://www.luogu.org/problemnew/show/2756 二分图网络流 鬼才去写网络流,输出方案?二分图匹配吧 网络流输出方案,枚举与汇点有流量的边,输出方案 #include<cstdio> #include<cstring> #include<algorithm> const int maxn = 10007; int m,n; inline int read() { int x=0,f=1;char c=getchar(); while

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

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

P2756 飞行员配对方案问题[二分图最大匹配]

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

734. [网络流24题] 方格取数问题 二分图点权最大独立集/最小割/最大流

?问题描述:在一个有m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意2 个数所在方格没有公共边,且取出的数的总和最大.试设计一个满足要求的取数算法.?编程任务:对于给定的方格棋盘,按照取数要求编程找出总和最大的数.?数据输入:由文件grid.in提供输入数据.文件第1 行有2 个正整数m和n,分别表示棋盘的行数和列数.接下来的m行,每行有n个正整数,表示棋盘方格中的数. [问题分析] 二分图点权最大独立集,转化为最小割模型,从而用最大流解决. [建模方法] 首先把棋盘黑白

P2756 飞行员配对方案问题 二分图匹配 匈牙利算法

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

「网络流24题」 题目列表

「网络流24题」 题目列表 序号 题目标题 模型 题解 1 飞行员配对方案问题 二分图最大匹配 <1> 2 太空飞行计划问题 最大权闭合子图 <2> 3 最小路径覆盖问题 二分图最小路径覆盖 <3> 4 魔术球问题 <4> 5 圆桌问题 <5> 6 最长递增子序列问题 <6> 7 试题库问题 <7> 8 机器人路径规划问题 <8> 9 方格取数问题 二分图最大点权独立集 <9> 10 餐巾计划问题

网络流24题小结

网络流24题 前言 网络流的实战应用篇太难做了,因此先完善这一部分 ## 第一题:飞行员配对方案 \(BSOJ2542\)--二分图 最优匹配 题意 两国飞行员\(x\)集合\(y\)集合,\(x\)飞行员可以配对特定的\(y\)集合的飞行员(可无),求一对一配对最大数 Solution 二分图最大匹配裸题,最大流实现 建图:(设\(i\in x\)而\(i'\in y\)) \((S,i,1)~(i',T,1)\) 对\((i,j')\)可匹配\((i,j',1)\) Code 略 ## 第二

网络流24题 2/24

我这种蒟蒻也要开始做网络流了啊qwq 飞行员配对方案问题 二分图匹配**题,匈牙利都能过 1 #include<bits/stdc++.h> 2 using namespace std; 3 bool vis[101]; 4 int match[101] , head[101] , cnt; 5 struct Edge{ 6 int end , upEd; 7 }Ed[10001]; 8 inline void add(int a , int b){ 9 Ed[++cnt].end = b;

线性规划与网络流24题

诈个尸. 1.飞行员配对方案问题 二分图匹配. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 using namespace std; 7 const int INF = 1e9; 8 const int maxn = 2e5 + 10; 9 int lv[maxn], it[ma