匈牙利算法

来源:互联网 发布:vue.js 2.0 教程下载 编辑:程序博客网 时间:2024/05/20 20:01

匈牙利算法

有vN 和uN两个点集构成的二分图 

通过深度遍历,       找u0-u1匹配增广轨 --------

  为u0找增光轨找到res++ 连线     

 为u1找增广轨找到res++连线  

 为u2找增广轨   假如u2能匹配v5,v6的都被u1,u0分别连接那么试图改变u1,u0的连接对象 给u2腾出v5或者v6位置 腾出来就连接res++ 

诸如此类直到整个遍历结


#include<iostream>#include<cstring>using namespace std;const int MAXN=510;int uN,vN;//u,v数目int g[MAXN][MAXN];            //图int linker[MAXN];bool used[MAXN];bool dfs(int u)         //从uN点集开始找增广路径{    int v;    for(v=0;v<vN;v++)               //对于每个u 遍历Vn点集,这个顶点编号从0开始      if(g[u][v]&&!used[v])         //如果这个uv顶点连通,且他还没有被used封锁  就是是增广轨      {          used[v]=true;               //这个顶点进行used封锁    本次dfs更深度递归不再使用       hungry 中u变化使used会初始化          if(linker[v]==-1||dfs(linker[v]))    //未被连线 直接连线 ||如果v点集的改点v'已经被连线 那么试图更改他连的曾经连接的u'的连线 让他成为未被连线 与当前u连线          {                                         //找增广路,反向              linker[v]=u;          //v u连线              return true;          }      }    return false;                                  //这里主要用于递归 判断非used封锁下 能够连线吗 就是能够腾位置吗}int hungry(){    int res=0;    int u;    memset(linker,-1,sizeof(linker));      //初始化linker 连线    for(u=0;u<uN;u++)                     //从uN点集遍历    {        memset(used,0,sizeof(used));          //初始化used        if(dfs(u)) res++;    }    return res;                       //返回最大点覆盖集}int main(){  while(cin>>uN>>vN)    {        for(int i=0;i<uN;i++)           for(int j=0;j<uN;j++)            {                cin>>g[i][j];            }        cout<<hungry();    }}



匈牙利算法详解参考:http://blog.csdn.net/dark_scope/article/details/8880547/   (写的很好,我是看着个看懂的:) )