二分图(代码片段)

hbhszxyb hbhszxyb     2023-03-20     252

关键词:

二分图

  1. 概念

    • 二分图:把一个图的顶点划分为两个不相交集 UV ,使得每一条边都分别连接UV中的顶点。如果存在这样的划分,则此图为一个二分图。二分图的一个等价定义是:不含有「含奇数条边的」的图。图 1 是一个二分图。为了清晰,我们以后都把它画成图 2 的形式。

      技术图片

    • 匹配:在图论中,一个「匹配」(matching)是一个集合,其中任意两条没有公共顶点。例如,图 3、图 4 中红色的边就是图 2 的匹配。

    • 我们定义匹配点匹配边未匹配点非匹配边,它们的含义非常显然。例如图 31、4、5、7 为匹配点,其他顶点为未匹配点;(1,5)(4,7)为匹配边,其他边为非匹配边。

    • 最大匹配:一个图所有匹配中,所含匹配边数最多的匹配,称为这个图的最大匹配。图 4 是一个最大匹配,它包含 4 条匹配边。

    • 完美匹配:如果一个图的某个匹配中,所有顶点都是匹配点,那么它就是一个完美匹配。图 4 是一个完美匹配。显然,完美匹配一定是最大匹配(完美匹配的任何一个点都已经匹配,添加一条新的匹配边一定会与已有的匹配边冲突)。但并非每个图都存在完美匹配

    • 举例来说:如下图所示,如果在某一对男孩和女孩之间存在相连的边,就意味着他们彼此喜欢。是否可能让所有男孩和女孩两两配对,使得每对儿都互相喜欢呢?图论中,这就是完美匹配问题。如果换一个说法:最多有多少互相喜欢的男孩/女孩可以配对儿?这就是最大匹配问题。

      技术图片

  2. 匈牙利算法,求解最大匹配问题的一个算法是匈牙利算法

    • 交替路:从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边…形成的路径叫交替路。如图5(9 ightarrow 4 ightarrow 8 ightarrow 1 ightarrow 6 ightarrow 2) 就是一条交替路。

    技术图片

    • 增广路:从一个未匹配点出发,走交替路,如果途径另一个未匹配点(出发的点不算),则这条交替路称为增广路(agumenting path)。例如,图 5 中的一条增广路如图 6 所示(图中的匹配点均用红色标出):

      技术图片

      • 增广路有一个重要特点:匹配边比匹配多一条。因此,研究增广路的意义是改进匹配
      • 只要把增广路中的匹配边非匹配边的身份交换即可。
      • 由于中间的匹配节点不存在其他相连的匹配边,所以这样做不会破坏匹配的性质。
      • 交换后,图中的匹配边数目比原来1 条。
      • 我们可以通过不停地找增广路来增加匹配中的匹配边和匹配点。找不到增广路时,达到最大匹配(这是增广路定理)。匈牙利算法正是这么做的。在给出匈牙利算法 DFS BFS 版本的代码之前,先讲一下匈牙利树。
    • 匈牙利树:一般由 BFS 构造(类似于 BFS 树)。从一个未匹配点出发运行 BFS(唯一的限制是,必须走交替路),直到不能再扩展为止。例如,由图 7,可以得到如图 8 的一棵 BFS 树:

      技术图片

      • 这棵树存在一个叶子节点为非匹配点(7 号),但是匈牙利树要求所有叶子节点均为匹配点,因此这不是一棵匈牙利树。如果原图中根本不含 7 号节点,那么从 2 号节点出发就会得到一棵匈牙利树。这种情况如图 9 所示(顺便说一句,图 8 中根节点 2 到非匹配叶子节点 7 显然是一条增广路,沿这条增广路扩充后将得到一个完美匹配)。
  3. 例题月老的难题

    Description

    • 月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘。
    • 现在,由于一些原因,部分男孩与女孩可能结成幸福的一家,部分可能不会结成幸福的家庭。
    • 现在已知哪些男孩与哪些女孩如果结婚的话,可以结成幸福的家庭,月老准备促成尽可能多的幸福家庭,请你帮他找出最多可能促成的幸福家庭数量吧。
    • 假设男孩们分别编号为(1sim n),女孩们也分别编号为 (1sim n)

    Input

    • 第一行是一个整数T,表示测试数据的组数(1<=T<=400)

    • 每组测试数据的第一行有两个整数n,K,其中男孩的人数与女孩的人数都是n。(n<=500,K<=10 000)

    • 随后的K行,每行有两个整数i,j表示第i个男孩与第j个女孩有可能结成幸福的家庭。(1<=i,j<=n)

    Output

    • 对每组测试数据,输出最多可能促成的幸福家庭数量

    Sample Input

    1
    3 4
    1 1
    1 3
    2 2
    3 2
    

    Sample Output

    2
    
    • Code

      #include <bits/stdc++.h>
      const int maxn=505;
      int vis[maxn];//访问标记数组,用来剪枝
      std::vector<int> g[maxn];//vector数组用来充当邻接表
      int girls[maxn];//女孩子的男朋友
      int n;//标记匹配的男生或者是女生的人数
      bool Find(int x)//匈牙利算法,参数x表示编号是x的男生找女朋友
          for(int i=0;i<g[x].size();i++)
              int y=g[x][i];//获取当前男生的每个女朋友
              if(vis[y]==0)//如果当前女生没有被访问过        
                  vis[y]=1;//标记访问
                  if(girls[y]==0||Find(girls[y]))//如果这个女生没有男朋友或者是递归查找这个女生的男朋友有备胎可以选择            
                      girls[y]=x;//那么这个女生就给这个男生分配
                      return true;//一旦分配了,相当于多了一对匹配了,就返回
                  
              
          
          return false;//如果最后也没有成功分配,那么就返回false
      
      int main()
          int T;scanf("%d",&T);
          while(T--)
              for(int i=0;i<maxn;i++)
                  g[i].clear();//初始化每个男生的喜欢的女孩子的编号为空
              int m;scanf("%d%d",&n,&m);
              for(int i=0;i<m;i++)
                  int v,u;scanf("%d%d",&u,&v);
                  g[u].push_back(v);//u的心仪对象是v号女孩
              
              memset(girls,0,sizeof(girls));//初始化所有女生的男朋友没有
              int ans=0;//男生匹配成功的数目为0
              for(int i=1;i<=n;i++)//遍历每一个男生        
                  memset(vis,0,sizeof(vis));//每次深搜前都初始化所以的女生都没有被访问过
                  if(Find(i))//如果当前男生成功被匹配
                      ans++;//成功数目+1
              
              printf("%d
      ",ans);//输出最终的答案
          
          return 0;
      
      
  4. 补充定义和定理

    • 最大匹配数:最大匹配的匹配边的数目
    • 最小点覆盖数:选取最少的点,使任意一条边至少有一个端点被选择
    • 最大独立数:选取最多的点,使任意所选两点均不相连
    • 最小路径覆盖数:对于一个 DAG(有向无环图),选取最少条路径,使得每个顶点属于且仅属于一条路径。路径长可以为 0(即单个点)。
    • 定理
      • 定理一:最大匹配数 = 最小点覆盖数(这是 Konig 定理)
      • 定理2:最大匹配数 = 最大独立数
      • 定理3:最小路径覆盖数 = 顶点数 - 最大匹配数

二分图二分图的多重匹配(代码片段)

某些问题中,会遇到一对多的二分图模型,即允许集合Y中的一个元素和集合X中的多个元素匹配(通常有一个最大限制n)/*二分图多重匹配算法*/constintMAXN=1001;//最大顶点数intbmap[MAXN][MAXN];//二分图boolbmask[MAXN];//寻找增广路径是的... 查看详情

二分图匹配(代码片段)

  记得很早就看过这个算法,但是一直没怎么学。  二分图:   无向图G为二分图的充分必要条件是,G至少有两个顶点,且其所有回路的长度均为偶数。   判断一个联通图是否是二分图采用着色法,选取一个起点... 查看详情

二分图匹配(代码片段)

先来看看一道题目:二分图匹配题目描述给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数输入格式:第一行,n,m,e第二至e+1行,每行两个正整数u,v,表示u,v有一条连边输出格式:共一行,二分图最大匹配输入... 查看详情

acm模板判断二分图+二分图最大匹配(代码片段)

参考文章:https://www.luogu.com.cn/blog/Repulser/solution-p3386POJ2492ABug’sLife判断无向图是否为二分图,注意图可能不连通。#include<iostream>#include<cstdio>#include<cstring>#include<vector> 查看详情

二分图匹配(模板)(代码片段)

二分图匹配附上两种方法:网络流据说所有的二分图题目都可以用网络流跑过去,可能还快一些话不多说,只有代码/*二分图匹配的题大多可用网络流做此处为Dinic模板,详见网络流模板*/#include<iostream>#include<cstdlib>#includ... 查看详情

785.判断二分图(代码片段)

利用二分图没有奇环的性质DFS:classSolutionprivate:staticconstexprintUNCOLORED=0;staticconstexprintRED=1;staticconstexprintGREEN=2;vector<int>color;boolvalid;public:voiddfs(intnode,intc,constvector<vector 查看详情

二分图板子(代码片段)

二分图最大匹配:匈牙利算法 邻接表O(mn):#pragmaGCCoptimize(2)#include<bits/stdc++.h>usingnamespacestd;constintmaxn=1010;constintmaxm=2e5;intn,m,t;intmch[maxn],vistime[maxn];structEintto,next;edge[maxm];in 查看详情

二分图匹配问题(代码片段)

二分图最大匹配 二分图最大权匹配1#include<bits/stdc++.h>2usingnamespacestd;3constintLEN=1e3+5;4typedeflonglongll;5intn,n1,n2,m;6constintoo=1e9;7llans;8namespaceKM9intqh,qt;10intw[LEN][LEN],q[LEN];11intlx[ 查看详情

hdu1669二分图多重匹配+二分(代码片段)

Jamie‘sContactGroupsTimeLimit:15000/7000MS(Java/Others)    MemoryLimit:65535/65535K(Java/Others)TotalSubmission(s):747    AcceptedSubmission(s):303ProblemDescri 查看详情

p1525关押罪犯-二分+二分图染色||并查集(代码片段)

传送门一.二分+二分图染色最小的最大,考虑二分。每次二分影响值,将影响值不小于mid的两个人关进不同的监狱,即染成不同的颜色,分到二分图的两个不同的集合中。若最终形成的图是二分图,说明这种分法可行,影响值还... 查看详情

二分图最大匹配(代码片段)

二分图的概念二分图又称作二部图,是图论中的一种特殊模型。设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(iinA,jinB),则称图G为... 查看详情

codeforcescf85eguardtowers二分答案二分图判定(代码片段)

$ightarrow$戳我进CF原题E.GuardTowerstimelimitpertest:1.5secondsmemorylimitpertest:256megabytesinput:standardinputoutputstandardoutput Inafarawaykingdomlivesaverygreedyking.Todefendhisland,hebuilt$n$guard 查看详情

evacuation(二分图)(代码片段)

Evacuation(二分图)DescribeFirescanbedisastrous,especiallywhenafirebreaksoutinaroomthatiscompletelyfilledwithpeople.Roomsusuallyhaveacoupleofexitsandemergencyexits,butwitheveryonerushingoutatthesametime,itmaytakeawhileforeveryonetoescape.Youaregiventhefloorplanofaroomandmustfindouthowmuchtimei... 查看详情

浅谈二分图(代码片段)

(一)二分图匹配给定一个二分图G,在G的一个子图M中,M的边集E中的任意两条边都不依附于同一个顶点,则称M是一个匹配。图中加粗的边是数量为2的匹配。(一)二分图判定如果一个图是连通的,可以用如下的方法判定是否... 查看详情

图论基础——二分图(代码片段)

二分图可以把图中所有顶点分到两个集合内,并且使得集合内部没有边。重要性质:一个图是二分图,当且仅当图中不含奇数环。一、染色法判二分图复杂度O(n+m)O(n+m)O(n+m)运用深度优先搜索对节点逐个染色&#x... 查看详情

图论基础——二分图(代码片段)

二分图可以把图中所有顶点分到两个集合内,并且使得集合内部没有边。重要性质:一个图是二分图,当且仅当图中不含奇数环。一、染色法判二分图复杂度O(n+m)O(n+m)O(n+m)运用深度优先搜索对节点逐个染色&#x... 查看详情

p1330封锁阳光大学-二分图染色(代码片段)

传送门根据题意可知二分图染色。若无法被染成二分图,输出Impossible;反之,对于每个二分图,记录两种颜色的点的个数,取min后记录答案中。注意,图可能不连通。因此对于每个二分图,都要进行取min操作,而不是对整个图... 查看详情

[图论][二分图判断]theaccomodationofstudents(代码片段)

ProblemDescriptionThereareagroupofstudents.Someofthemmayknoweachother,whileothersdon‘t.Forexample,AandBknoweachother,BandCknoweachother.ButthismaynotimplythatAandCknoweachother.Nowyouaregivenallpairso 查看详情