1.二分图的定义
二分图是一种特殊的无向图,它的节点可以被划分为两个互不相交的集合,使得同一集合中的任意两个节点之间没有边相连,而不同集合中的节点之间都有边相连。
换句话说,如果一个无向图可以被划分为两个集合,并且所有边的两个端点都分别属于不同的集合,那么这个无向图就是一个二分图。
如图,有蓝色,绿色两个集合,集合内的点可以跟另一个集合内的点相互连接,但集合内部不能连接,这就叫二分图。

那么如何判定是否为二分图呢?这就要用到二分图的染色
2.二分图的染色

假设图中的颜色都还没标上,只有点和边,那么我们需要对各个点能直达的点染色(也就是不同集合的点的染不同颜色),如果能符合“相邻点的颜色不同”这个条件,就是一个二分图。
反之如下,两个蓝色的点之间有连线,可是他们颜色相同,就不能满足条件了

例题1

1.用vector建图,此时我们已经知道了各个点(记作点i)的所有邻接点(也就是只用走一条边就能到达的点),那么点i的邻接点j的颜色不能跟点i一样
2.如果点i是蓝色,点j就应该被染成绿色
3.我们要将以点i为起点,所有能到达的点都遍历,可以用dfs或者bfs
4.如果染的过程中,某点还没有染色,就将其染成相反色;
如果已经染了色,且颜色为相反色,则不用管;
如果已经染了色,且颜色相同,说明不满足条件,这不是一个二分图。
dfs写法
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
bfs写法
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
例题2
D - Good Tuple Problem



分析:atcoder周赛,基本就是模板题了
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
3.匈牙利算法
匈牙利算法是用来求二分图的最大匹配数,注意!是最大匹配数,是无权的

假设有这些男生和女生,男生对一些女生中意,问怎么匹配才能让匹配出来的情侣数量最多
答:我们把下面的行为看成一个“追”的动作
男生i一个个访问自己中意的女生,如果该女生j还没有对象,则直接匹配成功。
如果女生j有对象,即match[j]这个男生,那么去找找看match[j]这个男生能不能换一个女朋友(即女生j有调整空间),然后把女生j让给男生i。如果可以,则男生i也匹配成功。
如果男生i遍历完所有中意的女生还是找不到,就匹配失败。

着重解释一下st[]。作用是不重复访问同一个女生,导致递归陷入死循环。
我们可以把st[]的作用看成一个“预定”的行为,当女生j还没被预定,则使其被预定,即st[j] = true,看看这个女朋友能不能追到手(也就是我上面“答”的部分)。不行的话去看看其他中意的女生。
注意!不论女生j追没追到手,她都已经是被”预定“过了,后续不能再访问。
那到底是怎么陷入死循环的呢?
如果没有st数组的情况如下。
当男生i访问到了女生j,女生j已经有男生k当男朋友了,那么此时就要看看男生k能不能换别的女朋友。所以男生k就会遍历所有自己中意的女生,看看有没有未被选的女生,或者有调整空间的女生。
问题就出在这里!这样的话男生k可能又会访问到女生j,然后看女生j有没有调整空间,也就是自己有没有调整空间,陷入递归死循环!
因此,st[]的存在是必要的。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include