实验报告
实验目的:
1、掌握最大匹配,交错路径的定义;
2、掌握最大匹配的求解方法。
实验要求:
输入:无向简单连通图的关联矩阵
(例如:))。
输出:此图的最大匹配
例如:M={e1,e3}
实验内容和实验步骤:
思路:输入关联矩阵,依次找到每一条边所对应的极大匹配,共找到m个(其中会有部分重复),再从m个极大匹配中找到最大匹配。
极大匹配的查找:用边集E记录一个极大匹配中包含的边,用点集V记录边集E所关联的所有点,首先在其中放入一条边,再依次遍历所有边,当存在某条边的两个端点都不在点集V中,则将该边放入边集E,两个端点放入点集E,遍历完后,即可得到一个极大匹配。
代码:
#include<iostream> #include<vector> #include<unordered_set> using namespace std; typedef vector<vector<int> > mat; typedef vector<unordered_set<int> > Arry;//用于储存极大匹配 int n = 0, m = 0; void getPP(int col, mat M, Arry& pps )//由边col找到一个极大匹配,并放入Arry中 { unordered_set<int>E;//边集:放匹配 unordered_set<int>V;//点集:放E中的边关联的所有点 E.insert(col);//将边col放入匹配中 for (int i = 0; i < n; i++) { if (M[i][col] == 1) { V.insert(i);//将边col的端点放入点集 } } for (int j = 0; j < m; j++) { int flag = 0;//记录找到了多少个点 int a = 0, b = 0;//记录两个点 for (int i = 0; i < n; i++) { if (M[i][j] == 1) { if (!V.count(i))//判断边i的两个端点是否已经包含点集V中 { flag++;//若点不包含在点集V中 if (flag == 1)//第一个点 { a = i; } if (flag == 2)//第二个点 { b = i; } } } } if (flag == 2)//若两点都不在点集V中,则将边j放入边集E,更新点集 { E.insert(j); V.insert(a); V.insert(b); } } pps.push_back(E);//将得到的极大匹配放入集合中 } int main() { cout << "请输入点数和边数:" << endl; cin >> n >> m; cout << "请输入关联矩阵:" << endl; mat glMatrix(n, vector<int>(m, 0)); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> glMatrix[i][j]; } } Arry pps;//储存极大匹配 for (int j = 0; j < m; j++)//遍历每条边 { getPP(j, glMatrix, pps);//得到m个极大匹配 } int max = 0; for (int i = 0; i < pps.size(); i++) { if (pps[i].size() > pps[max].size()) { max = i;//找到最大匹配 } } //输出最大匹配 cout << endl << "M = {"; int i = 0; for (auto it = pps[max].begin(); it != pps[max].end(); it++, i++) { cout << "e" << *it + 1; if (i != int(pps[max].size()) - 1) { cout << ","; } } cout << "}" << endl; cout << "β1 = " << int(pps[max].size()) << endl; }
实验测试数据、代码及相关结果分析:![](https://img-blog.csdnimg.cn/34db60880ae64ab98164058ef78c01d5.png)
实验总结:
通过本次实验,我学会了如何由关联矩阵求图的最大匹配,加深了我对最大匹配的理解。