算法学习:匈牙利算法

【定义】

【二分图】:整张图可以分成两个点集,集合中点互相之间无通路

【匈牙利算法】

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define MAX 2147483647
#define MAXN 1010
int match[MAXN];
int book[MAXN];
int t[MAXN][MAXN];
int n,m;
int s;
int dfs(int u)
{
     int i;
     for(i=1;i<=m;i++)//枚举每个结点
      {
         if(book[i]==0&&t[u][i]) //如果这个点没有被访问过,同时有点连接
          {
            book[i]=1;//使其被访问过
            if(match[i]==-1||dfs(match[i]))
                {
                            //如果这个点没有对应的点
                            //如果有,试着让这个点更换另外的点
                            //也就是我下面提到的更新连接对应的方式
                            //这个点和上面的位置连接
                            match[i]=u;
                            return 1;
                            //返回,这个点有连接的状态
                     }
              }
      }            
return 0;
}
int main()
{
    int i;
    scanf("%d%d%d",&n,&m,&s);
    for(i=1;i<=m;i++)
        match[i]=-1;
    int x,y;
    for(i=1;i<=s;i++)
     {
         scanf("%d%d",&x,&y);
         t[x][y]=1;
     }//读取二分图
    int sum=0;
    for(i=1;i<=n;i++)
     { 
       memset(book,0,sizeof(book));
       if(dfs(i))//逐个访问
       sum++;
     }
    printf("%d",sum);
    return 0;
}

以上是高中时候照啊哈算法写的板子,几年前写的,学过之后忘掉了,拿出来再复习一下

具体描述代码注释

我对于这个算法的理解是,
他其实就是一个暴力,暴力的尝试这种方法是否可行,如果可行的的话标记
不可行的话继续向下寻找,通过暴力寻找新的边的排布方式,给所需要扩展的这条边多出来一个位置的话,达到扩展的目地
新的扩展的这条路也有特定的名字,增广路

我觉得他和网络流求二分图匹配相似,无论是时间还是方法上,数据规模也都差不多

猜你喜欢

转载自www.cnblogs.com/rentu/p/12208413.html