zoukankan      html  css  js  c++  java
  • 匈牙利算法

    作用:用于求一个二分图中的最大匹配数。

    算法:一种类似手动模拟的一种暴力算法。

    说明:柯尼希定理:一个二分图的最大匹配数等于这个图中最小点覆盖数,最小点覆盖数(一条边上有一点覆盖即为该边覆盖,求覆盖所有边的最小点数)。柯尼希定理的推论:最小路径覆盖=节点数-最大匹配数(最小路径覆盖—选择最少不相交的边覆盖所有的点)只使用有向无环图。

    代码

    #include<iostream>
    #include<cstdio>
    #include<string.h>
    using namespace std;

    const int MaxN=510;

    int graph[MaxN][MaxN],flag[MaxN],nxt[MaxN];
    //graph为矩阵存图
    //flag标记M集合中的元素是否已有匹配点
    //nxt用于储存M中的元素匹配了N中的哪个点,next好像是关键字,所以写为nxt
    int N,M;

    bool Find(int x)//判断找点函数
    {
        for(int i=1;i<=M;++i)
        {
            if(graph[x][i]&&!flag[i])//判断两点间是否有边寄目标点是否已有匹配
            {
                flag[i]=1;
                if(nxt[i]==0||Find(nxt[i]))//此处递归,设计巧妙,只有在找到可行解之后再进行一下的重复赋值
                {
                    nxt[i]=x;//储存匹配点
                    return true;
                }
            }
        }
        return false;
    }

    int match()//匹配函数
    {
        int sum=0;
        for(int i=1;i<=N;++i)
        {
            memset(flag,0,sizeof(flag));//新的一轮新的匹配,标记M集合中的元素是否已有匹配点
            if(Find(i))//判断点i是否可以匹配上
                ++sum;
        }
        return sum;
    }

    int main()
    {
        memset(graph,0,sizeof(graph));//初始化
        memset(nxt,0,sizeof(nxt));
        int T,u,v;
        scanf("%d%d%d",&T,&N,&M);
        while(T--)
        {
            scanf("%d%d",&u,&v);//存边
            graph[u][v]=1;
        }
        int ans=match();
        printf("%d ",ans);
        return 0;


    }

  • 相关阅读:
    PHP 使用 GET 传递数组变量
    Java实现 蓝桥杯 算法训练 数据交换
    Java实现 蓝桥杯 算法训练 数据交换
    Java实现 蓝桥杯 算法训练 数据交换
    Java实现 蓝桥杯 算法训练 景点游览
    Java实现 蓝桥杯 算法训练 景点游览
    Java实现 蓝桥杯 算法训练 景点游览
    Java实现 蓝桥杯 算法训练 二进制数数
    Java实现 蓝桥杯 算法训练 二进制数数
    Java实现 蓝桥杯 算法训练 二进制数数
  • 原文地址:https://www.cnblogs.com/l1l1/p/8986968.html
Copyright © 2011-2022 走看看