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的主要内容,如果未能解决你的问题,请参考以下文章