room 二分图最大匹配KM

Posted profish

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了room 二分图最大匹配KM相关的知识,希望对你有一定的参考价值。

#include<bits/stdc++.h>
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pqueue priority_queue
#define NEW(a,b) memset(a,b,sizeof(a))
const double pi=4.0*atan(1.0);
const double e=exp(1.0);
const int maxn=1e5+8;
typedef long long LL;
typedef unsigned long long ULL;
const LL mod=1e9+7;
const ULL base=1e7+7;
using namespace std;
struct room{
    int s[4];
}a[110],b[110];
inline int get(room x,room y){
    int sum=0;
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++){
            if(x.s[i]==y.s[j]){
                sum++;
            }
        }
    }
    return sum;
}
int cx[110],cy[110];
int ch[110][110];
bool visx[110],visy[110];
int lx[110],ly[110],slack[110];
int n;
inline bool dfs(int u){
    visx[u]=1;
    for(int i=0;i<n;i++){
        if(!visy[i]){
            int tmp=lx[u]+ly[i]-ch[u][i];
            if(tmp==0){
                visy[i]=1;
                if(cy[i]==-1||dfs(cy[i])){
                    cx[u]=i;
                    cy[i]=u;
                    return 1;
                }
            }
            else{
                slack[i]=min(slack[i],tmp);
            }
 
        }
    }
    return 0;
}
inline void KM(){
    memset(cy,-1,sizeof(cy));
    memset(cx,-1,sizeof(cx));
    for(int i=0;i<n;i++){
        lx[i]=-INF;
        ly[i]=0;
        for(int j=0;j<n;j++){
            lx[i]=max(lx[i],ch[i][j]);
        }
    }
    for(int u=0;u<n;u++){
        for(int i=0;i<n;i++){
            slack[i]=INF;
        }
        while(1){
            memset(visx,0,sizeof(visx));
            memset(visy,0,sizeof(visy));
            if(dfs(u)) break;
            int inc=INF;
            for(int i=0;i<n;i++){
                if(!visy[i]){
                    inc=min(inc,slack[i]);
                }
            }
            for(int i=0;i<n;i++){
                if(visx[i]){
                    lx[i]-=inc;
                }
            }
            for(int i=0;i<n;i++){
                if(visy[i]){
                    ly[i]+=inc;
                }
                else{
                    slack[i]-=inc;
                }
            }
        }
    }
}
int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        for(int j=0;j<4;j++){
            scanf("%d",&a[i].s[j]);
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<4;j++){
            scanf("%d",&b[i].s[j]);
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            ch[i][j]=get(a[i],b[j]);
        }
    }
    KM();
    int sum=0;
    for(int i=0;i<n;i++){
        sum+=ch[i][cx[i]];
    }
    sum=4*n-sum;
    printf("%d
",sum);
}

 

以上是关于room 二分图最大匹配KM的主要内容,如果未能解决你的问题,请参考以下文章

km算法(二分图最大权匹配)学习

二分图最大权值匹配 KM算法 模板

km板子(二分图最大权匹配)

HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法

[kuangbin带你飞]专题十 匹配问题 二分图最大权匹配

HDU 2255 KM算法 二分图最大权值匹配