二分图最大匹配

来源:互联网 发布:网络大电影榜单 编辑:程序博客网 时间:2024/05/01 06:43

主要思想是匈牙利算法刚开始去网上搜了很多,,,但是上面的术语太多。。。那个增广路径刚开始没看懂。。。。后来自己琢磨一下。。。。

  原理是这样的、、、从二分图的一个子集A的点Ai开始匹配。若Ai与子集B中的点Bj相连。此时Bj有两种可能:一种是Bj还未匹配,还有一种情况则是Bj已经与Aj匹配,但通过搜索Aj可以与其他点匹配。这两种情况均可以把Ai与Bj匹配,记做:link[Bj]:=Ai
杭电水题http://acm.hdu.edu.cn/showproblem.php?pid=2063

  

const int N = 50;const int M = 50;bool use[M];//记录y中节点是否使用int link[M];//记录当前与y节点相连的x的节点:i未加入匹配时为link[i]==0bool g[N][M];//记录连接x和y的边,如果i和j之间有边则为1,否则为0int gn,gm;//二分图中x和y中点的数目bool find(int v)//对x中的结点v,找增广路径。{    int i;    for(i = 1; i <= gm; i++)//对结点v发出的每条边    {       if(g[v][i] && !use[i])       {           use[i] = true;//如果y中的结点i还没有加入到匹配中(link[i]==0),可直接连线;  //或者y加入到了匹配中,根据link[i]找到x中的结点v,根据v发出的边寻找另外一个未加入匹配结点y  //找到就记录到link中,返回true;找不到返回false(即找增广路径)。           if(link[i] == 0 || find(link[i]))           {              link[i] = v;              return true;           }       }    }    return false;}int MaxMatch()//找二分图的最大匹配数。{    int i,ans=0;    for(i = 1; i <= gn; i++)    {       memset(use,0,sizeof(use));       if(find(i)) ans++;    }return ans;}

原创粉丝点击