二分图完美匹配
完美匹配模板题,注意包含多组数据。
贴上代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,k;
int cost[305][305];
int who[305];
int lx[305],ly[305],slack[305];
bool f[305],s[305];
bool dfs(int i){
s[i]=true;
for (int j=1;j<=n;j++){
if (f[j])
continue;
int pd=lx[i]+ly[j]-cost[i][j];
if (!pd){
f[j]=true;
if (!who[j]||dfs(who[j])){
who[j]=i;
return true;
}
}
else
slack[j]=min(slack[j],pd);
}
return false;
}
int main(){
while (scanf("%d",&n)==1){
memset(cost,0,sizeof(cost));
memset(ly,0,sizeof(ly));
memset(lx,0,sizeof(lx));
memset(who,0,sizeof(who));
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++){
scanf("%d",&cost[i][j]);
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
lx[i]=max(lx[i],cost[i][j]);
for (int i=1;i<=n;i++){
memset(slack,0x7f,sizeof(slack));
while (1){
memset(s,false,sizeof(s));
memset(f,false,sizeof(f));
if (dfs(i))
break;
int m=0x7fffffff;
for (int j=1;j<=n;j++)
if (!f[j])
m=min(m,slack[j]);
for (int j=1;j<=n;j++){
if (s[j])
lx[j]-=m;
if (f[j])
ly[j]+=m;
else slack[j]-=m;
}
}
}
int ans=0;
for (int i=1;i<=n;i++)
ans+=cost[who[i]][i];
printf("%d\n",ans);
}
return 0;
}