二分图最大匹配

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

  原理是这样的、、、从二分图的一个子集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]==0
bool g[N][M];		//记录连接x和y的边,如果i和j之间有边则为1,否则为0
int 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;
}

你可能感兴趣的:(算法)