二分图: 又称作二部图,是图论中一种特殊模型。设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中每条边所关联的两个顶点 i 和 j 分别属于这两个不同的顶点集( i ∈ A , j ∈ B i \in A,j \in B i∈A,j∈B),则称图G为一个二分图。
简单来说,如果图中所有顶点可以被分为两个集合,图中所有的边的头和尾不属于同一个顶点集合,而是跨越两个集合,则这个图是一个二分图。
二分图当且仅当图中不含奇数环
如何判断二分图?染色法
// 判断从某个节点出发,是否所有连通节点都满足相邻节点不同颜色
bool dfs(std::vector<std::vector<int>> &graph, std::vector<int> &st, int i, int color)
{
// 之前被染色的情况
if (st[i])
{
if (st[i] == color) return true;
else return false; // st[i] != color 矛盾
}
st[i] = color;
for (int j: graph[i])
{
// 颜色1、2之间的切换可以用3-color
if(!dfs(graph, st, j, 3 - color)) return false;
}
return true;
}
// 检查邻接表graph是否为二分图
bool check(std::vector<std::vector<int>> &graph)
{
int n = graph.size();
std::vector<int> st(n, 0); // st: 标记染色,0(未染色),1和2为相邻节点颜色。
bool ans = true;
for (int i = 0; i < n; i ++)
{
if (!st[i] && !dfs(graph, st, i, 1))
{
ans = false;
break;
}
}
return ans;
}
import sys
# 设置递归栈次数
sys.setrecursionlimit(100000)
def dfs(graph, st, i, color):
if st[i]:
if st[i] == color:
return True
else:
return False
st[i] = color
for j in graph[i]:
if not dfs(graph, st, j, 3 - color):
return False
return True
def check(graph):
n = len(graph)
st = [0 for _ in range(n)]
ret = True
for i in range(n):
if not st[i] and not dfs(graph, st, i, 1):
ret = False
break
return ret
// find: 对于集合1的点i,找集合2的匹配对象,成功返回true
// graph: 邻接表
// match: 记录集合2的匹配对象,没有匹配为-1
bool find(std::vector<std::vector<int>> &graph, std::vector<int> &macth, std::vector<bool> &st, int i)
{
for (int j: graph[i])
{
// 已经访问了集合2的对象j,那么跳过
if (st[j]) continue;
st[j] = true;
// j没有被匹配或者j之前的匹配对象macth[j]可以另外被配对
if (macth[j] == -1 || find(graph, macth, st, macth[j]))
{
macth[j] = i;
return true;
}
}
return false;
}
// hungarian: 求二分图最大匹配,返回最大匹配数量
// graph: 邻接表
// n1: 集合1大小
// n2: 集合2大小
int hungarian(std::vector<std::vector<int>> &graph, int n1, int n2)
{
int ans = 0;
// match: 记录集合2的匹配对象,没有匹配为-1
std::vector<int> macth(n2, -1);
for (int i = 0; i < n1; i ++)
{
// st: 记录每次查找是否访问了集合2中的对象
std::vector<bool> st(n1, false);
if (find(graph, macth, st, i)) ans ++;
}
return ans;
}
def find(graph, macth, st, i):
for j in graph[i]:
if st[j]:
continue
st[j] = True
if macth[j] == -1 or find(graph, macth, st, macth[j]):
macth[j] = i
return True
return False
def hungarian(graph, n1, n2):
ans = 0
match = [-1 for _ in range(n2)]
for i in range(n1):
st = [False for _ in range(n2)]
if find(graph, match, st, i):
ans += 1
return ans
SORT算法原理(匈牙利匹配+卡尔曼滤波跟踪)