KM remember learning algorithm of bipartite graph bipartite graph maximum weight perfect match.

Pre-knowledge:  Hungarian algorithm

First, there is such a map, find the maximum weight this picture of a perfect match.

Of course, if you do not want to see these dregs map, you can go to the Valley of Los  optimal matching of athletes

Let me explain KM force algorithm

Sister left to find a group of men, but each sister to have a good impression of Chinese characters is not the same, we first take a look at the biggest favorability of each sister's [expectations] is how much, and temporarily put maximum favorability Chinese characters [expectations] set 0

Now sister's dream can not be achieved, let's take a look

A man looking to NO.1

This picture has an obvious feature is the edge weight between each sister and let her have a favorable impression of the man expected to total less than equal to the maximum value of the sister.

With my junior high school math test bombing experience, to tell you when to take, etc., you will not live up to the expectations of sister

Become, no matter what the next contradiction, we went looking for it to man B

NO.2 find a man to B

Now it seems there is no contradiction, then my sister came in C

NO.3 C to find sister

Seemingly not so easy, because B has been and c together

Now how to do it? Consultation about it, C said to B: "(Brothers Sound) or else that you fancy a change  you and I step back now."

B: also

But the man c BC saw this fight  and my heart suddenly proud, so proud of their value add 1

Now it is not that easy to handle yet.

So this picture maximum weight of 11 is the perfect match

Pseudo-code will be easier

void 匈牙利()
{
    判断访问妹子 
    遍历她的汉子们 
    返回 
 } 


void km()
{
    for(每个点)  //根据定义,每个点都能求到最大权 完美 匹配 的
    {
      for(尝试n次||while 1) //这两个一个意思
      {
          if(求到妹子汉子之间期望值之和等于边权→匈牙利算法 ) break;
          刷新妹子的期望值;
          刷新汉子的骄傲值;
          //不要忘了 每次匈牙利算法清空 vis 
       } 
    } 
 } 

所以上一段代码,题就是开头的 运动员最佳匹配问题

#include<iostream>
#include<cmath>
#include<queue>
#include<cstring>
#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>

using namespace std;

int n,m,love[50][50],lx[50],ly[50];
int vx[50],vy[50],bd[50],tot,mmn;

int dfs(int t)
{
    if(vx[t])return 0;
    vx[t]=1;
    int i;
    for(i=1;i<=n;i++)
    {
        if(vy[i]) continue;
        int p=lx[t]+ly[i]-love[t][i];
        if(!p)
        {
            vy[i]=1;
            if(dfs(bd[i])||!bd[i])
            {
                bd[i]=t;
                return 1;
            }
        }
        else if(p>0) 
        mmn=min(mmn,p);
    }
    return 0;
}

void km()
{
    int i,j;
    for(i=1;i<=n;i++)
    {
        while(1)
        {
            mmn=0x3f3f3f3f;
            memset(vx,0,sizeof(vx));
            memset(vy,0,sizeof(vy));
            if(dfs(i)) break;
            for(j=1;j<=n;j++)
            {
                if(vx[j]) lx[j]-=mmn;
                if(vy[j]) ly[j]+=mmn;
            }
        }
    }
}


int main()
{
    scanf("%d",&n);
    int i,j;
    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    scanf("%d",&love[i][j]);
    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    {
        int t;
        scanf("%d",&t);
        love[j][i]*=t;
    }
    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    {
        lx[i]=max(love[i][j],lx[i]);
    }
    km();
    for(i=1;i<=n;i++)
    tot+=love[bd[i]][i];
    printf("%d",tot);
    return 0; 
}

 

Guess you like

Origin www.cnblogs.com/zsx6/p/11116762.html