二分图完美匹配
仍然是练手题,实在打不来的童鞋可以试试搜索暴力(毕竟n只有20)
要注意输入格式。
贴上代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int w[25][25],who[25];
int x[25][25],y[25][25];
int lx[25],ly[25];
int n;
int slack[25];
bool fx[25],fy[25];
bool dfs(int i){
fx[i]=true;
for (int j=1;j<=n;j++){
if (!fy[j]){
int sum=lx[i]+ly[j]-w[i][j];
if (!sum){
fy[j]=true;
if (!who[j]||dfs(who[j])){
who[j]=i;
return true;
}
}
else
slack[j]=min(slack[j],sum);
}
}
return false;
}
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
scanf("%d",&x[i][j]);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
scanf("%d",&y[i][j]);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
w[i][j]=x[i][j]*y[j][i];
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
lx[i]=max(lx[i],w[i][j]);
for (int i=1;i<=n;i++){
memset(slack,0x7f,sizeof(slack));
while (1){
memset(fx,false,sizeof(fx));
memset(fy,false,sizeof(fy));
if (dfs(i))
break;
int m=0x7fffffff;
for (int j=1;j<=n;j++)
if (!fy[j])
m=min(m,slack[j]);
for (int j=1;j<=n;j++){
if (fx[j])
lx[j]-=m;
if (fy[j])
ly[j]+=m;
else
slack[j]-=m;
}
}
}
int ans=0;
for (int i=1;i<=n;i++)
ans+=w[who[i]][i];
printf("%d\n",ans);
return 0;
}