什么是图? 这里增加一个link来讲解图
首先二分图https://baike.baidu.com/item/%E4%BA%8C%E5%88%86%E5%9B%BE/9089095是一个无向图 G = ( V, E ),
其次,如果顶点 V 可以分成两个相互不相交的子集(A,B),
并且图中的每条边(i, j)所关联的两个顶点 i, j分别属于两个不同的顶点集,
则这个图G为一个二分图。
特点:
1.顶点集V可以分成两个不相交的子集(A,B)
2.每条边的两个顶点分别属于两个子集
3.子集内部的顶点不相邻
二分图的匹配
匹配
在二分图G的一个子图M(1,4,5,6,3,7)中,M的边集(1,2,3)中,任意两条边都没有相同的顶点,则称这个子集M是一个匹配。
极大值匹配
在当前已完成的匹配下,无法再通过增加未完成匹配的边的方式来增加匹配的边数
最大匹配
所有极大匹配当中边数最大的一个匹配
完全匹配
一个匹配中,图中的每个顶点都和图中某条边相关联
如何判断一个图是不是二分图?
染色法
用两种颜色,代表A,B两种集合,标记所有顶点。如果相邻的顶点之间颜色不同,那么这个图就是一个二分图
// 分别用深度优先和广度优先搜索实现
vector<int> G[maxn]; // 存边
int col[maxn]; // 标记顶点颜色
int n,m; // 点和边的个数
bool bfs(){
queue<int> q;
q.push(1); // 放入第一个点
memset(col,0,sizeof(col));
col[1] = 1; // 先标记第一个点为1
while(!q.empty()){
int v = q.front();
q.pop();
for(int i=0;i<G[v].size();i++){
int xx = G[v][i];
if(col[xx] == 0){ // 判断这个点是否标记过
col[xx] = -col[v]; // 没有标记过就标记上与v相反的颜色
q.push(xx);
}
else{
if(col[v] == col[xx]){ // 如果颜色冲突说明不是二分图
return false;
}
}
}
}
return true;
}
求二分图的匹配
匈牙利算法和最大流