存图的两种方式:
1.邻接矩阵
#include<iostream>
#include<cstirng>
using namespace std;
#define maxn 1000
int mat[maxn][maxn];
int main()
{
//初始化
memset(mat,0,sizeof(mat));
//增加从i到j权值为w的点
mat[i][j] = w;
//删除
mat[i][j] = 0;
}
2.邻接表
#include<iostream>
#include<cstirng>
#include<vector>
using namespace std;
#define maxn 10000
vector<int>e[v];
int main()
{
int i,j,k;
//初始化
//将起点为i的链表初始化
e[i]. clear();
//增加边
//增加从i到j的边
e[i].push_back(j);
//查询以i为起点的第j条边;
e[i][j];
//寻找权值为k的边
for (int j = 0; j < (int)e[i].size(); j++)
{
if (e[i][j] == k)
{
//do something
}
}
}
二分图:
相关定理:
最大匹配数:最大匹配的匹配边的数目
最小点覆盖数:选取最少的点,使任意一条边至少有一个端点被选择
定理1:最小点覆盖数 = 最大匹配数(这是 Konig 定理)
最小路径覆盖数:对于一个 DAG(有向无环图),选取最少条路径,使得每个顶点属于且仅属于一条路径。路径长可以为 0(即单个点)。
二分图模型:把所有顶点 i 拆成两个:X集合中的 i 和Y集合中的 i’。若有边 i->j,则在二分图中引入边 i->j’。
定理2:最小路径覆盖数 = 顶点数 - 最大匹配数
扫描二维码关注公众号,回复:
4216286 查看本文章
最大独立集:选出一些顶点使得这些顶点两两不相邻,则这些点构成的集合称为独立集。找出一个包含顶点数最多的独立集称为最大独立集。
定理3:最大独立集 = 所有顶点数-最小点覆盖数
最大团:简单说,就是选出一些顶点,这些顶点两两之间都有边。最大团就是使得选出的这个顶点集合最大。
定理4二分图的最大团 = 补图的最大独立集
补图的定义是:对于二分图中左边一点x和右边一点y,若x和y之间有边,那么在补图中没有,否则有。
1.匈牙利算法
对于一个二分图,我们想办法为其左侧的每一个点选择一个右侧的点进行匹配。
那么成功找到一个匹配的方式有两种:
1.当前搜到节点还未被匹配,直接匹配上即可。
2.当前搜到的节点已被匹配,尝试让 当前点的匹配点 去匹配其他点,从而把当前点让出来用于匹配。
特别注意:对于每一条边,要连接两次,连双向边!!(左右点的标号不能重复!)