You were just hired as CEO of the local junkyard.One of your jobs is dealing with the incoming trash and sorting it for recycling.The trash comes every day in
N containers and each of these containers contains certain amount of each of the
N types of trash. Given the amount of trash in the containers find the optimal way to sort the trash. Sorting the trash means putting every type of trash in separate container. Each of the given containers has infinite capacity. The effort for moving one unit of trash from container
i to
j is 1 if
i ≠
j otherwise it is 0.You are to minimize the total effort.
The first line contains the number
N (1 ≤
N ≤ 150), the rest of the input contains the descriptions of the containers.The (1 +
i)-th line contains the description of the
i-th container the
j-th amount (0 ≤ amount ≤ 100) on this line denotes the amount of the
j-th type of trash in the
i-th container.
You should write the minimal effort that is required for sorting the trash.
4 62 41 86 94 73 58 11 12 69 93 89 88 81 40 69 13output
650题意: 有n个垃圾桶,每个垃圾桶内有n种垃圾,现在是要你把垃圾分类,到每一个垃圾桶最后都只能装一种垃圾,从一个垃圾桶里把垃圾移到另一个垃圾桶会有所消耗,且都是单位消耗。。
那么,要总消耗最少,就要原来每个垃圾桶各自保留的垃圾总和要最多,这么看来,问题就可以转化为带权二分图的最佳匹配问题。
求出这个最佳匹配 k 最后 ans = s(所有垃圾总和)-k
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define Inf 0x3f3f3f3f
using namespace std;
const int N = 200;
int dx[N],dy[N];
int vx[N],vy[N];
int match[N],slack[N];
int e[N][N];
int n;
int Find(int u){
vx[u]=1;
for(int i=1;i<=n;i++){
if(vy[i]) continue;
int gap=dx[u]+dy[i]-e[u][i];
if(gap==0){
vy[i]=1;
if(match[i]==-1||Find(match[i])){
match[i]=u;
return 1;
}
}
else slack[i]=min(gap,slack[i]);
}
return 0;
}
int KM(){
memset(dx,0,sizeof(dx));
memset(dy,0,sizeof(dy));
memset(match,-1,sizeof(match));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dx[i]=max(dx[i],e[i][j]);
for(int i=1;i<=n;i++){
memset(slack,Inf,sizeof(slack));
while(1){
memset(vx,0,sizeof(vx));
memset(vy,0,sizeof(vy));
if(Find(i)) break;
int dis=Inf;
for(int j=1;j<=n;j++)
if(!vy[j]) dis=min(dis,slack[j]);
for(int j=1;j<=n;j++){
if(vx[j]) dx[j]-=dis;
if(vy[j]) dy[j]+=dis;
else slack[j]-=dis;
}
}
}
int ans=0;
for(int i=1;i<=n;i++){
if(match[i]!=-1) ans+=e[match[i]][i];
}
return ans;
}
int main(){
scanf("%d",&n);
int sum=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
scanf("%d",&e[i][j]);
sum+=e[i][j];
}
printf("%d\n",sum-KM());
return 0;
}