二分图(又称为二部图)定义:
什么是二分图?
二分图是一种图的类型。二分图中顶点集合 V 中包含两种点的集合,不妨设为 Black 和 White,那么 V = Black ∩ White。二分图也满足:任何相同集合中的点不会连边(只有 Black 中的节点才能连接 White 中的节点),且每条边都是无向边。

举个栗子,有黑点和白点各 4 个,那么 图1 便是一个二分图:

图1

二分图基本常识:二分图判定
判定一个图是否是一个二分图,可以用二分图染色判定法(染色法 Colour Algorithm)

染色法经典题型

洛谷 P1525 关押罪犯
我们不妨把每个犯人看作一个节点,那么就是将集合 V 拆分成两类点,不妨设为 Black 和 White。那么需保证 Black 中的每个节点的连线和 White 中的每个节点的连线都保证小于等于 ans。我们可以用二分创造答案,用二分图判定卡特算法判断是否成为二分图。

设有一节点 i,maxx为二分的答案,那么可以枚举所有与 i 相邻并且边大于maxx的所有节点 j,若 j 未染色,则把 j 染成不同于 i 的颜色。若 j 已染色,则判断 j 的颜色是否不同于 i,若不是,则染色失败。这个过程可以用bfs来做。

#include<bits/stdc++.h>
using namespace std;
int n,m,b,ans;
int x,y,s;
vector<int>v[20005],z[20005];
int c[20005];
bool flag;
bool check(int maxx)//bfs主要过程
{queue<int>q;memset(c,0,sizeof c);for(int k=1;k<=n;k++){if(!c[k])//还未染色{q.push(k);c[k]=1;//默认染成 1while(!q.empty()){int i=q.front();q.pop();for(int j=0;j<v[i].size();j++)//枚举所有超过怨恨值的犯罪 jif(v[i][j]>maxx){if(!c[z[i][j]])//未染色{c[z[i][j]]=c[i]%2+1;//染成不同颜色q.push(z[i][j]);}else{if(c[z[i][j]]==c[i])return 0;//染色失败}}}}}return 1;
}
void search(int l,int r)//二分答案
{if(l>r)return;int mid=(l+r)>>1;if(check(mid)){ans=mid;search(l,mid-1);}else search(mid+1,r);
}
int main()
{cin>>n>>m;for(int i=1;i<=m;i++){cin>>x>>y>>s;v[x].push_back(s);z[x].push_back(y);v[y].push_back(s);z[y].push_back(x);b=max(b,s);}search(0,b);cout<<ans;return 0;
}

之后我们来讲讲二分图匹配中的概念:

匹配:每个点只能和能连接的点匹配,一个点最多匹配其他的一个点,将此匹配的子图称为子图 M。
最大匹配:子图 M 中最多的匹配。(如下图)

完美匹配(完备匹配):子图 M 中包含所有的节点的最大匹配。

这里强调一下,完美匹配一定是最大匹配,而最大匹配不一定是完美匹配。

匈牙利算法

假如现在有黑点和白点各 4 个, 那么如何匹配才能使所得的匹配数最多呢?

首先,我们看 W1,它可以和 B1 组成匹配,那么匹配(太直接了吧)。

我们看 W2,它最喜欢的是 B1,但 B1 已经和 W1 匹配了,就强行把它们两个分开了。W1 不服气,去找 B3 匹配了。


W3 也找到了自己的伙伴 B2 匹配。但这时 W4 看见自己唯一的 B2 被匹配了,很伤心。B2 也只好改为跟 W4 匹配。幸运的是,W3 并没有生气,它则是找 B4匹配了。


这便是此二分图的最大匹配,也是完美匹配,更是匈牙利算法的流程。通过流程,我们可以很轻松地编出匈牙利算法主要的核心代码。

#include<iostream>
#include<cstring>
using namespace std;
int n,m,g[105][105],sum;
int W[105];//Bi 的匹配对象
bool u[105];//本轮匹配,Bi是否被匹配
bool dfs(int i)//本轮匹配,Wi 是否能匹配
{for(int j=1;j<=n;j++)if(g[i][j]&&!u[j]){u[j]=1;//本轮匹配已匹配 if(!W[j]||dfs(W[j]))//Bj没有匹配对象,或可以给它的匹配对象重新再找一个匹配对象 {W[j]=i;return 1;}}return 0;
}
int main()
{cin>>n>>m;for(int i=1;i<=m;i++){int w,b;cin>>w>>b;g[w][b]=1; }for(int i=1;i<=n;i++)//一共有 n 轮匹配,每轮匹配匹配 Wi{memset(u,0,sizeof u);//每轮都清空一次 sum+=dfs(i);//匹配 Wi } cout<<"一共能匹配"<<sum<<"对\n\n";for(int i=1;i<=n;i++)if(W[i]){cout<<'W'<<W[i]<<" - "<<'B'<<i<<'\n';}return 0;
}

代码运行如下:

二分图(二部图)学习笔记(概念与匈牙利算法)相关推荐

  1. 【学习笔记】多项式相关算法

    [学习笔记]多项式相关算法 手动博客搬家: 本文发表于20181125 13:19:28, 原地址https://blog.csdn.net/suncongbo/article/details/844 ...

  2. Apollo星火计划学习笔记——Apollo开放空间规划算法原理与实践

    文章目录 前言 1. 开放空间规划算法总体介绍 1.1 Task: OPEN_SPACE_ROI_DECIDER 1.2 Task: OPEN_SPACE_TRAJECTORY_PROVIDER 1. ...

  3. Boost库学习笔记(二)算法模块-C++11标准

    Boost库学习笔记(二)算法模块-C++11标准 一.综述 Boost.Algorithm是一系列人通用推荐算法的集合,虽然有用的通用算法很多,但是为了保证质量和体积,并不会将太多通用算法通过审查测 ...

  4. 【学习笔记】目标检测算法总结

    [学习笔记]目标检测算法总结 说明 MacOS操作系统. MindNote思维导图软件. B站学习视频+原论文学习. 初学者 笔记 如有问题请多多指教 记录 Overfeat模型.R-CNN.Fast ...

  5. C++ Primer 学习笔记 第十章 泛型算法

    C++ Primer 学习笔记 第十章 泛型算法 336 find函数 #include <iostream> #include <vector> #include <s ...

  6. LVS学习笔记--概念

    最近在学习南非蚂蚁大大的博客上的一些文章,主要在学习LVS,现在就是将自己学习到的内容记录下来,做一个学习笔记与大家分享. 南非蚂蚁大大的博客是http://ixdba.blog.51cto.com ...

  7. opencv进阶学习笔记14:分水岭算法 实现图像分割

    基础版学习笔记目录: python3+opencv学习笔记汇总目录(适合基础入门学习) 进阶版笔记目录链接: python+opencv进阶版学习笔记目录(适合有一定基础) 分水岭算法原理 分水岭算法 ...

  8. 学习笔记——Kaggle_Digit Recognizer (SVM算法 Python实现)

    本文是个人学习笔记,该篇主要学习SVM算法概念,并应用sklearn.svm算法包解决Kaggle入门级Digit Recognizer. SVM 简述 经典SVM思想 SVM 线性不可分 SVM 多 ...

  9. 学习笔记——Kaggle_Digit Recognizer (KNN算法 Python实现)

    本文是个人学习笔记,该篇主要学习KNN算法理论和应用范围,并应用KNN算法解决Kaggle入门级Digit Recognizer,也是个人入坑ML和Kaggle的开端,希望能够有始有终. KNN算法 ...

最新文章

  1. 快手推荐系统及 Redis 升级存储
  2. 离职后竟半夜偷溜回办公室写代码?一个为自由软件而战斗的程序员
  3. iphone备忘录突然没了_苹果突然下架12 天猫:双11有惊喜!iPhone12 mini配色缩水
  4. PlacementBrowser源码分析
  5. 计算机专业合成词,大学计算机论文范文大全.docx
  6. 2020 年 7 个软件开发趋势
  7. linux搭建测试环境常见问题,在Linux环境下搭建CCID测试环境
  8. 神奇的python(六)之python的串口操作(pyserial)
  9. silverlight 中缓存应用程序相应的库文件
  10. Centos7#Linux基础富文本笔记
  11. 一些dalao的博客
  12. 银行面试常考。手把手带你高质量刷题(答案+解析)
  13. 解决win10每次重启后桌面图标排列混乱的问题。
  14. UDP网络基础知识简介
  15. 谈笑间学会数仓—主题域数据域
  16. poj_1363_Rai
  17. 【电容知识】之【NPO X7R Y5V 电容规格细谈】
  18. 计算机信息机房,计算机信息机房工程全面解决方案模板.docx
  19. 为什么敏捷方法能在软件开发中行之有效
  20. Snappy压缩库安装和使用之一

热门文章

  1. HTML5和CSS3 WEB技术开发
  2. python查看虚拟环境列表_Python虚拟环境简明教程
  3. MATLAB 怎样将for循环转换为矩阵【MATLAB 入门笔记 1】
  4. mysql 离散度低 索引_mysql给离散度低的字段建立索引会出现什么问题,具体说下原因。...
  5. 你见过凌晨四点破解密码的john吗?
  6. 湖北移动魔百盒CM201-1-YS_S905L2_RTL8822_emmc_双内存-当贝桌面线刷固件包
  7. JQuery qrcode插件生成二维码,并转换为image图片可识别
  8. java addall 顺序_Java LinkedList addAll()方法
  9. 【R语言-生存分析之观察生存率计算】
  10. 老片影像修复-DeepRemaster