定义:

如果一张无向图的N个节点(N>=2)可以分成A B两个非空子集,其中A∩B=Ø,并且在同一集合内的点之间没有相连的边,则称这张无向图为二分图。A,B分别成为这个图的左部和右部。

定理:

一张无向图是二分图,当且仅当图中不存在奇环(长度为奇数的环)。

证明:

下面用反证法来证明。
假设X中的顶点x1与x2是邻接的,那UX1,X1X2,X2U就构成了一个环,这个环的长度为奇数;这与H不具有奇环相矛盾。因此,X中不存在相邻接的顶点。同样可以证明Y中也不存在相邻接的顶点。这样,我们就构造出非琐碎组件H的两个集合X与Y,X与Y是不相交的,X中任意两个顶点都不是邻接的;同样Y中任意两个顶点也都不是邻接的。因此H是二分的。同样可以证明所有其它的G的组件都是二分的。因此也就证明了不具有奇环的图是二分图。

匹配:

我们将这种两两不含公共端点的边合集M成为成为匹配,而元素最多的边集M则称为二分图的最大匹配。当二分图的匹配书等于2倍节点数的时候,这个匹配就称为原二分图的完美匹配(完备匹配)

最大匹配:

匈牙利算法(增广路算法):稍微给你们提一句:

//二分图最大匹配数量
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=505;
int line[N][N];
int girl[N],used[N];
int k,m,n;
bool found(int x)
{for(int i=1; i<=n; i++){if(line[x][i]&&!used[i]){used[i]=1;if(girl[i]==0||found(girl[i])){girl[i]=x;return 1;}}}return 0;
}
int main()
{int x,y;while(scanf("%d",&k)&&k){scanf("%d %d",&m,&n);memset(line,0,sizeof(line));memset(girl,0,sizeof(girl));for(int i=0; i<k; i++){scanf("%d %d",&x,&y);line[x][y]=1;}int sum=0;for(int i=1; i<=m; i++){memset(used,0,sizeof(used));if(found(i)) sum++;}printf("%d\n",sum);}return 0;
}

 二分图的最佳完美匹配:

二分图的最佳完美匹配就是在完备匹配的基础上,每条匹配边都有他的权值,要使权值最大化,最大化权值的完备匹配。

#include <iostream>
#include <cstring>
#include <cstdio>using namespace std;
const int MAXN = 305;
const int INF = 0x3f3f3f3f;int love[MAXN][MAXN];   // 记录每个妹子和每个男生的好感度
int ex_girl[MAXN];      // 每个妹子的期望值
int ex_boy[MAXN];       // 每个男生的期望值
bool vis_girl[MAXN];    // 记录每一轮匹配匹配过的女生
bool vis_boy[MAXN];     // 记录每一轮匹配匹配过的男生
int match[MAXN];        // 记录每个男生匹配到的妹子 如果没有则为-1
int slack[MAXN];        // 记录每个汉子如果能被妹子倾心最少还需要多少期望值int N;bool dfs(int girl)
{vis_girl[girl] = true;for (int boy = 0; boy < N; ++boy) {if (vis_boy[boy]) continue; // 每一轮匹配 每个男生只尝试一次int gap = ex_girl[girl] + ex_boy[boy] - love[girl][boy];if (gap == 0) {  // 如果符合要求vis_boy[boy] = true;if (match[boy] == -1 || dfs( match[boy] )) {    // 找到一个没有匹配的男生 或者该男生的妹子可以找到其他人match[boy] = girl;return true;}} else {slack[boy] = min(slack[boy], gap);  // slack 可以理解为该男生要得到女生的倾心 还需多少期望值 取最小值 备胎的样子【捂脸}}return false;
}int KM()
{memset(match, -1, sizeof match);    // 初始每个男生都没有匹配的女生memset(ex_boy, 0, sizeof ex_boy);   // 初始每个男生的期望值为0// 每个女生的初始期望值是与她相连的男生最大的好感度for (int i = 0; i < N; ++i) {ex_girl[i] = love[i][0];for (int j = 1; j < N; ++j) {ex_girl[i] = max(ex_girl[i], love[i][j]);}}// 尝试为每一个女生解决归宿问题for (int i = 0; i < N; ++i) {fill(slack, slack + N, INF);    // 因为要取最小值 初始化为无穷大while (1) {// 为每个女生解决归宿问题的方法是 :如果找不到就降低期望值,直到找到为止// 记录每轮匹配中男生女生是否被尝试匹配过memset(vis_girl, false, sizeof vis_girl);memset(vis_boy, false, sizeof vis_boy);if (dfs(i)) break;  // 找到归宿 退出// 如果不能找到 就降低期望值// 最小可降低的期望值int d = INF;for (int j = 0; j < N; ++j)if (!vis_boy[j]) d = min(d, slack[j]);for (int j = 0; j < N; ++j) {// 所有访问过的女生降低期望值if (vis_girl[j]) ex_girl[j] -= d;// 所有访问过的男生增加期望值if (vis_boy[j]) ex_boy[j] += d;// 没有访问过的boy 因为girl们的期望值降低,距离得到女生倾心又进了一步!else slack[j] -= d;}}}// 匹配完成 求出所有配对的好感度的和int res = 0;for (int i = 0; i < N; ++i)res += love[ match[i] ][i];return res;
}int main()
{while (~scanf("%d", &N)) {for (int i = 0; i < N; ++i)for (int j = 0; j < N; ++j)scanf("%d", &love[i][j]);printf("%d\n", KM());}return 0;
}

图论--二分图--二分图的定义及其判断定相关推荐

  1. 二分图 二分图最大匹配

    首先来说一下什么是二分图. 二分图 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V, E)是一个无向图.如果顶点集V可分割为两个互不相交的子集X和Y,并且图中每条边连接的两个顶点一个在X中, ...

  2. NOI图论算法:二分图匹配

    二分图匹配 算法竞赛入门经典训练指南+陈锋+ch5.5_二分图的匹配 https://www.bilibili.com/video/BV1j5411x7PU SWPU-ACM每周算法讲堂-匈牙利算法 ...

  3. 图论——入门级二分图最大匹配Bipartite Matching

    1.问题描述 我们先来了解一下相关图论的概念: 二分图:又称二部图.是图论中的一种特殊模型.设G=(V,E)是一个无向图,如果结点集V可分割为两个互不相交的子集(V1,V2),并且图中的每条边(i,j ...

  4. 图论 —— 二分图 —— 二分图判定

    二分图的判定问题比较少见,简单来说,就是对于给定的图,判断图是否为二分图. 可以把每个节点着以黑色和白色之一,使得每条边的两个端点颜色不同,不难发现,对于一个当且仅当每个连通分量都是二分图,因此我们只 ...

  5. 图论:二分图多重匹配

    使用最大流和费用流解决二分图的多重匹配 之前编辑的忘存了好气啊.. 本来打算学完二分图的乱七八糟的匹配之后再去接触网络流的,提前撞到了 之前我们说的二分图最大匹配和二分图最大权匹配有一个特点,那就是没 ...

  6. 图论之二分图-HihoCoder1121

    题目链接:https://hihocoder.com/problemset/problem/1121 二分图的相关概念:https://blog.csdn.net/qq_36345036/articl ...

  7. 【图论】二分图学习笔记

    找不到题了,今天最后一个坑给二分图学习笔记吧,明天回来填. 12点之前发完10篇,ye~ 如果一张无向图的N个节点可以分成A,B两个非空集合,并且同一集合内的点之间都没有边相连的话,那么称这张图为二分 ...

  8. 二分图 恶补定义!!!

    二分图:是这样一个图,其顶点可分为两集合X和Y,所有的边关联的两顶点中,恰一个属于X,另一个属于Y.同一集合的结点不相邻. 匹配:图的一个匹配是一些边的集合,任意两条边没有公共点. 最大匹配:包含边数 ...

  9. 图论(二分图最大权独立点集):COGS 2051. 王者之剑

    2051. 王者之剑 ★★★☆   输入文件:Excalibur.in   输出文件:Excalibur.out   简单对比 时间限制:1 s   内存限制:256 MB [题目描述] 这是在阿尔托 ...

最新文章

  1. git操作手册_基本的Git手册
  2. 美团点评基于 Flink 的实时数仓建设实践
  3. 译-在Python正则模式中search()和match()的区别是什么?
  4. linux 编译环境包,linux上war包编译环境搭建(示例代码)
  5. 数据结构(一)线性表链式存储实现
  6. 真正的动态声明性组件
  7. XYZ DOWN-电子书
  8. 【华为云技术分享】ARMv8-A存储模型概述(2)
  9. Mac查看Python安装路径和版本
  10. 【例题】给定一个浮点格式(IEEE 754),有k位指数和n位小数,对于下列数,写出阶码E、尾数M、小数f和值V的公式。另外,请描述其位表示。
  11. Python爬虫之(二)工具的使用
  12. unidac连接ORACLE免装客户端驱动
  13. linux中的ps fx命令,Linux中的ps命令
  14. Windows8下设置VS默认启动方式为管理员启动
  15. arp***的判断与解决方案总结
  16. 球球大作战JAVA小游戏
  17. Ubuntu20.04安装搜狗拼音
  18. IIS6.0文件解析漏洞
  19. linux let命令详解,Linux命令:let(示例代码)
  20. 实训一#1.7F1方程式冠军

热门文章

  1. Please make sure you have the correct access rights and the repository exists.报错问题
  2. Android开发之ConstraintLayout(约束布局)一个控件位于一个控件右上角类似RelativeLayout实现效果
  3. 制定交叉编译工具_配置交叉编译工具链-嵌入式Linux
  4. ArcGIS Desktop新建postgresql版sde(10.4.1)的连接
  5. 【PHP高级特性】之反射
  6. ElasticSearch概述和定义
  7. Redis的几个认识误区
  8. lightoj 1224
  9. Nagios监控系统详解
  10. Android 百度地图Demo