Time Limit: 4000MS | Memory Limit: 65536K | |
Total Submissions: 11530 | Accepted: 3892 |
Description
Input
Output
Sample Input
1 3 3 1 1 1 0 1 1 1 2 2 1 0 1 1 2 3 1 1 1 2 1 1 1 1 1 3 2 20 0 0 0
Sample Output
4 -1 题意:n个店,m个供货点,k种货物。一个n*k的矩阵代表第i个店主对第j种货物的需求,接下来的m*k行,表示第i个供货点第j种的货物。在接下来的k个n*m个矩阵表示,第j个供货点供给第i个店的第k种货物的花费。求最小花费。
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define INF 9999999 #define maxn 205 int lx[maxn],ly[maxn]; int w[maxn][maxn]; int Match[maxn],visx[maxn],visy[maxn]; int slack[maxn]; int ans,n,m,k; int need[maxn][maxn],have[maxn][maxn],cost[maxn][maxn][maxn]; int indexA[maxn],indexB[maxn]; int A,B; bool findPath(int x) { int tmp; visx[x]=1; for(int y=1; y<=B; y++) { if(visy[y])continue; if(w[x][y]==lx[x]+ly[y]) { visy[y]=1; if(!Match[y]||findPath(Match[y])) { Match[y]=x; return true; } } else slack[y]=min(slack[y],w[x][y]-lx[x]-ly[y]); } return false; } void km() { memset(Match,0,sizeof(Match)); memset(ly,0,sizeof(ly)); for(int i=1; i<=A; i++) { lx[i]=INF; for(int j=1; j<=B; j++) lx[i]=min(lx[i],w[i][j]); } for(int x=1; x<=A; x++) { for(int i=1; i<=B; i++) slack[i]=INF; while(true) { memset(visx,0,sizeof(visx)); memset(visy,0,sizeof(visy)); if(findPath(x))break; int tmp=INF; for(int i=1; i<=B; i++) { if(!visy[i]) { if(tmp>slack[i]) tmp=slack[i]; } } if(tmp==INF)return ; for(int i=1; i<=A; i++) if(visx[i])lx[i]+=tmp; for(int i=1; i<=B; i++) if(visy[i])ly[i]-=tmp; } } } int main() { int cas; while(scanf("%d%d%d",&n,&m,&k)) { if(n==0&&m==0&&k==0)break; int a,b,c; ans=0; for(int i=1; i<=n; i++) for(int j=1; j<=k; j++) { cin>>need[i][j]; } for(int i=1; i<=m; i++) for(int j=1; j<=k; j++) { cin>>have[i][j]; } for(int i=1; i<=k; i++) for(int j=1; j<=n; j++) for(int l=1; l<=m; l++) scanf("%d",&cost[i][j][l]); int flag1=0; for(int i=1; i<=k; i++) { int sumNeed=0,sumHave=0; for(int j=1; j<=n; j++) sumNeed+=need[j][i]; for(int j=1; j<=m; j++) sumHave+=have[j][i]; if(sumNeed>sumHave) { flag1=1; cout<<"-1"<<endl; break; } } if(flag1)continue; for(int i=1; i<=k; i++) { A=0; B=0; for(int j=1; j<=n; j++) for(int l=1; l<=need[j][i]; l++) indexA[++A]=j; for(int j=1; j<=m; j++) for(int l=1; l<=have[j][i]; l++) indexB[++B]=j; for(int j=1; j<=A; j++) for(int l=1; l<=B; l++) w[j][l]=cost[i][indexA[j]][indexB[l]]; km(); //int flag=0; for(int i=1; i<=B; i++) { if(Match[i]) ans+=w[Match[i]][i]; } } cout<<ans<<endl; } return 0; }