网络流之二分图最大匹配

前言:二分图最大匹配往往用于普通的指派问题中,可转换为最大流问题求解,也可以利用二分图的性质及其边的容量为1的特点,简单的实现二分图的最大匹配算法。

问题模型:有n台计算机和k个任务,每台计算机处理的任务种类不同,问如果给每台计算机分配一个任务,一次最多能处理多少个任务。

分析:该问题可以转化为图论模型来分析。设U为所有计算机顶点的集合,V为所有任务类型的集合,u属于U,v属于V,e=(u,v)表示计算机u能处理任务v,E是所有e的集合。

则G=(U||V, E),且G中满足两两不含公共端点的边的集合的最大值,就是我们所要求的最大任务数即二分图中的最大匹配。如果此问题转为最大流求解,只需增加一个源点s

和汇点t,从源点到所有计算机连一条容量为1的有向边,从所有任务到终点t也连一条容量为1的有向边,再在计算机与所能处理的任务之间连一条容量为1的有向边,时间复杂度同求解最大流的一样。当然,考虑到所有边的容量均为1及二分图的性质,我们还可以简单实现二分图的最大匹配算法,时间复杂度O(VE)。

//二分图最大匹配算法的简单实现

#include <iostream>
#include <vector>
using namespace std;

vector<int> G[1000];
int match[1000];
bool used[1000];

int dfs(int v)
{//通过深搜寻找增广路O(E)
   used[v] = 1;
   for(int i = 0; i < G[v].size(); ++i)
   {
      int u = G[v][i], w = match[u];
      if(w == -1 || (!used[w] && dfs(w)))
      {
         match[u] = v;
         match[v] = u;
         return 1;
      }
   }
   return 0;
}

void solve(int n, int k, int e)
{
   int i, j, ans = 0;
   memset(match, -1, sizeof(match));
   for(i = 0; i < n + k; ++i)
   {
      if(match[i] != -1)
         continue;
      memset(used, 0, sizeof(used));
      if(dfs(i))

      ++ans;
  }
   cout << ans << endl;
}

int main()
{
   int n, k, e;
   cin >> n >> k >> e;
   for(int i = 0; i < e; ++i;)
   {
      int u, v;
      cin >> u >> v;
      G[u - 1].push_back(n + v - 1);
      G[n + v - 1].push_back(u - 1);
   }
   solve(n, k, e);
   return 0;
}

时间: 2024-10-11 12:41:45

网络流之二分图最大匹配的相关文章

最小路径覆盖问题(网络流,二分图) &amp; 最小路径点覆盖结论证明

最小路径覆盖问题(luogu) 题目描述 给定有向图 G=(V,E) .设 P 是 G 的一个简单路(顶点不相交)的集合. 如果 V 中每个定点恰好在PP的一条路上,则称 P 是 G 的一个路径覆盖. P 中路径可以从 V 的任何一个定点开始,长度也是任意的,特别地,可以为 0 . G 的最小路径覆盖是 G 所含路径条数最少的路径覆盖.设计一个有效算法求一个 GAP (有向无环图) G 的最小路径覆盖. 输入格式 第一行有 2 个正整数 n 和 m . n 是给定 GAP(有向无环图) G 的顶

【网络流-二分图最大匹配】poj3041Asteroids

/* 这道题将每行x看成是结点x,没列y看成是结点y,而障碍物的坐标xy看成是从x到y的 一条边.建图后问题就变成了,找最少的点,使得这些点与所有的边相邻,即最小 点覆盖,用匈牙利算法解决. ------------------------------- 定理:最小点覆盖数 = 最大匹配数,即求图的最大匹配即可,匈牙利算法 ------------------------------- 模板讲解: bool find(int v) { for(int i=1; i<=n; i++) { if(g

【网络流#6】POJ 3041 Asteroids 二分图最大匹配 - 《挑战程序设计竞赛》例题

学习网络流中ing...作为初学者练习是不可少的~~~构图方法因为书上很详细了,所以就简单说一说 把光束作为图的顶点,小行星当做连接顶点的边,建图,由于 最小顶点覆盖 等于 二分图最大匹配 ,因此求二分图最大匹配即可. 邻接矩阵,DFS寻找增广路,匈牙利算法 邻接矩阵:复杂度O(n^3) 如果使用邻接表:复杂度O(n*m) #include<cstdio> #include<cstring> #include<cmath> #include<iostream>

图论——LCA、强联通分量、桥、割顶、二分图最大匹配、网络流

A: 交通运输线 时间限制: 5 Sec  内存限制: 128 MB 题目描述 战后有很多城市被严重破坏,我们需要重建城市.然而,有些建设材料只能在某些地方产生.因此,我们必须通过城市交通,来运送这些材料的城市.由于大部分道路已经在战争期间完全遭到破坏,可能有两个城市之间没有道路.当然在运输线中,更不可能存在圈. 现在,你的任务来了.给你战后的道路情况,我们想知道,两个城市之间是否存在道路,如果存在,输出这两个城市之间的最短路径长度. 输入 第一行一个整数Case(Case<=10)表示测试数据

二分图最大匹配[网络流]

题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每行两个正整数u,v,表示u,v有一条连边 输出格式: 共一行,二分图最大匹配 建模: s--1-->X--1-->Y--1-->t 注意:边的数量 PS:本题比hungary快了5倍 // // main.cpp // 二分图dinic // // Created by Candy on 29/11/2016. // Copyri

hihoCoder 1393 网络流三&#183;二分图多重匹配(Dinic求二分图最大多重匹配)

#1393 : 网络流三·二分图多重匹配 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来. 小Hi和小Ho作为班上的班干部,统计分配比赛选手的重任也自然交到了他们手上. 已知小Hi和小Ho所在的班级一共有N名学生(包含小Hi和小Ho),编号依次为1..N. 运动会一共有M项不同的比赛,编号为1..M.第i项比赛每个班需要派出m[i]名选手参加. 根据小Hi和小Ho的统计,编号为i的学生表示最多同时参加

51nod 2006 飞行员配对(二分图最大匹配) 裸匈牙利算法 求二分图最大匹配题

题目: 题目已经说了是最大二分匹配题, 查了一下最大二分匹配题有两种解法, 匈牙利算法和网络流. 看了一下觉得匈牙利算法更好理解, 然后我照着小红书模板打了一遍就过了. 匈牙利算法:先试着把没用过的左边的点和没用过的右边的点连起来, 如果遇到一个点已经连过就试着把原来的拆掉 把现在这条线连起来看能不能多连上一条线. 总结来说就是试和拆,试的过程很简单,拆的过程由于使用递归写的,很复杂.很难讲清楚,只能看代码自己理会. 代码(有注释): #include <bits\stdc++.h> usin

Codevs1232飞行员配对方案问题【二分图最大匹配】

Codevs上的Special Judge似乎挂了 所以就跑到COGS上交 http://cojs.tk/cogs/problem/problem.php?pid=14 14. [网络流24题] 搭配飞行员 ★★☆   输入文件:flyer.in   输出文件:flyer.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾驶员.由于种种原因,例如相互配合的问题

51Nod 2006 飞行员配对(二分图最大匹配)-匈牙利算法

2006 飞行员配对(二分图最大匹配) 题目来源: 网络流24题 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 第二次世界大战时期,英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2名飞行员,其中1名是英国飞行员,另1名是外籍飞行员.在众多的飞行员中,每一名外籍飞行员都可以与其他若干名英国飞行员很好地配合.如何选择配对飞行的飞行员才能使一次派出最多的飞机.对于给定的外籍飞行员与英国飞行员的