OUC离散数学II实验四C++

实验四  图的最大匹配

实验目的:

  1. 掌握最大匹配,交错路径的定义;
  2. 掌握最大匹配的求解方法。

实验要求

输入:无向简单连通图的关联矩阵

(例如:A=   10011110000001111001 )。

输出:此图的最大匹配

例如:M={e1,e3}

实验内容和步骤

  1. 第一步先处理输入的关联矩阵

上次助教检查时,学长告诉我vector有另一种声明方式,更简洁。

  1. 用最大匹配的定义,最大的边不相邻的边盖集。

先创建两个无序的set存放(标记)使用过的边和点

这里先将e1和e1对着的两个点放进去避免冗余的情况。

每条边判断是否和其他标记过的边相邻,然后放到Edge中。

最后直接输出

实验结果:实验结果(包括输入与输出形式如下所示)

结果截图:

下面附上源码

#include <iostream>

#include <vector>

#include <unordered_set>

using namespace std;



int main()

{

    int n = 0; // 顶点

    int m = 0; // 边

    cout << "请输入图的顶点数和边数:" ;

    cin >> n >> m;



    vector<vector<int> > Matrix(n, vector<int>(m, 0));

    //另一种vector的声明方式



    for (int i = 0; i < n; ++i)

    {

        for (int j = 0; j < m; ++j)

        {

            cin >> Matrix[i][j];

        }

    }



    unordered_set<int> Edge;

    unordered_set<int> Vertex;

    Edge.insert(0); // 先加入e1,假设每次都包含e1



    for (int i = 0; i < n; ++i)

    {

        if (Matrix[i][0] == 1)

        {

            Vertex.insert(i);

        }

    }



    for (int j = 1; j < m; ++j)

    {

        int flag = 0; // 为2的时候说明该边不和匹配中的边相邻,即两个端点都不在Vertex

        int t1 = -1;

        int t2 = -1;



        for (int i = 0; i < n; ++i)

        {

            if (Matrix[i][j] == 1)

            {

                if (Vertex.count(i) == 0)

                {

                    flag++;//一个不在

                    if (t1 == -1)

                    {

                        t1 = i;

                    }

                    else if (t2 == -1)

                    {

                        t2 = i;

                    }

                    else

                    {

                        cout << "一条边不可能有超过两个顶点,输入出错了";

                        return 0;

                    }

                }

            }

        }

        // 该边可以加入匹配中

        if (flag == 2)

        {

            Vertex.insert(t1);

            Vertex.insert(t2);

            Edge.insert(j);

        }

    }



    cout << "该图的一个最大匹配集为:";

    auto iter = Edge.begin();

    cout << "{e" << *iter + 1;



    ++iter;



    for (; iter != Edge.end(); ++iter)

    {

        cout << ", e" << *iter + 1;

    }



    cout << "}" <<endl;



    return 0;

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值