匈牙利算法

来源:互联网 发布:商家入驻一元夺宝源码 编辑:程序博客网 时间:2024/06/06 01:42

比如有三个人 要选择礼物,每个人都有自己喜欢的礼物,如果拿不到喜欢的礼物,宁愿放弃

int a[4][4] = { {0}, {0, 1,1 }, { 0, 0, 1,1 }, { 0, 1 } }; 第一个人喜欢第1、2个礼物

第二个喜欢第2,3个礼物,第三个人喜欢第一个礼物,问最佳匹配能匹配多少个

算法;

该算法共涉及三个数组:

a[][]  行表示人 、列表示礼物、如果a[i][j]为1,表是该人喜欢该礼物,行、列都从1算起

visit[i]: 表示第i个人是否选到礼物

gift[i]; 表示第i个礼物被谁选走了

步骤

从第一个人开始,a[person][i] :依次查找第一个不为0,目的是找到第person个人喜欢哪个礼物,如果gift【1】没有被别人选走,则把gift【1】设为1,表示第1个礼物被第person个人选走了,返回1

 如果gift【1】被别人选走,回溯,让gift【1】这个人重新再找,如果他找到了就可以把现在gift【1】设为person,表示成功 返回1, 否则返回失败


#include <stdio.h>

int  visit[4];
int  gift[4];
int a[4][4] = { {0}, {0, 1,1 }, { 0, 0, 1,1 }, { 0, 1 } };
int num = 4;

int  DFS(int person )
{
    int i;


    for (i = 1; i < num; ++i)
    {
        if (a[person][i] != 0 && 0== visit[person])
        {
            visit[person] = 1;
            if (gift[i] == 0 )
            {
                gift[i] = person;
                return 1;

                
            }
            else if (DFS(gift[i]))
            {
                gift[i] = person;//一定要先让第gift【i】个人找到礼物 再把gift[i]重新赋值,之前也不能把gift[i]清0,否则就会进入死循环了
                return 1;

                
            }
            
        }

    }
    return 0;

}

void rset(int a[])
{
    int i = 0;
    for (i = 0; i < num; i++)
    {
        a[i] = 0;
    }
}

int main(void)
{
    

    int result=0;


    int i,  m,tmp,k;
    m = num;
    
    for (i = 1; i < m; i++)
    {
        rset(gift);  //此处是为了把之前的结构清零,不是特别理解 。。。。。。。。
        tmp = DFS(i);
        if (0!=tmp)
        {
            result += tmp;
        }
        
        for (k = 1; k < m; k++)
        {
            printf("%d ", gift[k]);

        }
        printf("\n");
    }


    for (i = 1; i < m; i++)
    {
        printf("%d ",gift[i]);

    }
    printf("result =%d \n",result);


    return 0;

}
0 0
原创粉丝点击