匈牙利算法的理解

匈牙利算法注重在于增广路的查找。图的两个点可以分为两个集合A,B。A B集合之间的关系就是图的边。现在让图的边数值最大。对每一个点找增广路(就是看每一边能不能扩展原本的路径n+1),在查找第i个点的增广路时候,如果B集合K的点已经被别人选择了,则尝试让B的点能否在不损失原本路径的长度上让位置给当前节点,那么需要回溯K的父亲节点,看他有没有其他增广路径长度为n并且可以让第i个点的增广路符合。注重腾空间过程,记住每一轮都要初始化used数组 并且在fin函数中走过一次就要设值为1不然会死循环

#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
int map[1000][1000],f[1000],used[1000];
int n,m,bian;
int Fin(int x)
{
    for(int i=1;i<=m;i++)
    {
        if(map[x][i]==1&&used[i]==0)
        {
            used[i]=1;
            if(f[i]==0||Fin(f[i]))
            {
                f[i]=x;
                return 1;
            }
        }
    }
    return 0;
}
int main()
{
    scanf("%d %d %d",&n,&m,&bian);
    memset(f,0,sizeof(f));
    memset(map,0,sizeof(map));
    for(int i=1;i<=bian;i++)
    {
        int a,b;
        scanf("%d %d",&a,&b);
        map[a][b]=1;
    }
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        memset(used,0,sizeof(used));
        if(Fin(i)) ans++;
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hnust_lizeming/article/details/80409854