匈牙利算法(二分图算法

匈牙利算法用于求二分图的最大匹配:

used[]表示当前这次循环中已经被占用的右边节点,linker[i]记录第i个右边节点归属于那个左边节点,下列u表示左边节点,v表示右边节点。对于邻接矩阵存储的结构:

//先来先得,但是是能让就让

bool dfs(int u){     //对左边的u节点进行分配的调整,若能分配返回true
    for(int v=0;v<vN;v++)
        if(g[u][v]&&!used[v]){//有边相连,并且**这次**还没考虑过v点
        used[v]=1;    //只要遍历过的used都置为1
        //若右边v节点还没有归属,或者v的原来归属 可以分配另外节点
        if(linker[v]==-1||dfs(linker[v])){
            linker[v]=u;
            return true;
    /*只要当前图中存在一个used[i]==0&&linker[i]==-1的v,所有递归就都解决了,
      dfs(u)返回的就是true。
      1.  used==1实际上表示的就是“维持观望”的状态(对于维持观望的位置used==1,
      说明这个位置原来有人,但在未找到下家之前,该位置不会腾出,
      所以就不用再挤过去),但只要出现一个点的linker[i]=-1没被占用,
      那之前维持观望的点都能找到新下家,返回true。
      2.  如果大家都是维持观望,说明没有新位置可以腾出,
          大家都找不到新下家,返回false*/
        }
    	}
    return false;
}

int hungary(){
    int res;
    for(int u=0;u<uN;u++){
        memset(used,0,sizeof(used));   //每次对左边新点做调整时,对used重置
        if(dfs(u)) res++;    //一次dfs确定左边一个新点u的匹配
    }
    return res;    //返回二分图最大匹配数
}


趣谈匈牙利算法 kuangbin模板

1538.Gopher II

直接用最大二分图匹配,建图可采用邻接表,对于距离小于s*t的田鼠和洞的组合之间建立一条边,然后用最大二分图匹配让最多的田鼠能入洞,最终答案是没入洞的田鼠数。

做的时候没有对基于vector的邻接表clear更新,要注意对vector以及其他公用结构更新!

你可能感兴趣的:(noi.openjudge)