题目大意:就是有n个商家然后n行是对应每个商家对k件物品的需求量。然后m行分别代表每个供应区可以提供k件物品的数量,下面是k个n*m的矩阵代表第k个物品,从j供应区运到i需求商的费用。
思路:我们可以分k次求最小费用最大流。这题挺简单的就是源点连供应区,供应区连供应商,供应商连汇点。但是注意数组一定要开大!否则可能WA。能想到的话注意是不是即使刚开始满足供应,但是最后不一定可以供应的问题。
#include<iostream> #include<cstdio> #include<cstring> #include<map> #include<queue> #include<algorithm> #define MAX 1000 #define inf 0x3f3f3f3f using namespace std; struct no{ int d[64]; }p[64]; struct nod{ int nu[64]; }p1[64]; struct node{ int a[64][64]; }p2[64]; struct node1{ int to,next,w,c; }q[30024]; int star,en,head[30024],cnt,flow,minflow,cost,dis[3024],qu[10024],cur[10024]; bool vis[3024]; int f[10024]; void bu(int a,int b,int w,int c){ q[cnt].to=b; q[cnt].w=w; q[cnt].c=c; q[cnt].next=head[a]; head[a]=cnt++; q[cnt].to=a; q[cnt].w=0; q[cnt].c=-c; q[cnt].next=head[b]; head[b]=cnt++; } bool SPFA(){ memset(vis,false,sizeof (vis) ); memset(dis,inf,sizeof (dis) ); dis[star]=0; vis[star]=true; cur[en]=cur[star]=-1; f[star]=inf; int f1,f2;f1=f2=0; qu[f1++]=star; while(f1>f2){ int u=qu[f2++]; vis[u]=false; for(int i=head[u];~i;i=q[i].next){ int v=q[i].to; if(dis[v]>dis[u]+q[i].c&&q[i].w>0){ dis[v]=dis[u]+q[i].c; f[v]=min(f[u],q[i].w); cur[v]=i; if(!vis[v]){ vis[v]=true; qu[f1++]=v; } } } } if(dis[en]>=inf)return false; flow+=f[en]; cost+=f[en]*dis[en]; for(int i=cur[en];~i;i=cur[q[i^1].to]){ q[i].w-=f[en]; q[i^1].w+=f[en]; } return true; } int main(){ int n,m,i,j,k,SS; while(~scanf("%d%d%d",&n,&m,&k)){ SS=0; if(!n&&!m&&!k) break; cost=0; for(i=1;i<=n;i++){ for(j=1;j<=k;j++){ scanf("%d",&p[i].d[j]); } } for(i=1;i<=m;i++){ for(j=1;j<=k;j++) scanf("%d",&p1[i].nu[j]); } for(i=1;i<=k;i++){ for(int x=1;x<=n;x++){ for(int y=1;y<=m;y++){ scanf("%d",&p2[i].a[x][y]); } } } bool bj=false; for(j=1;j<=k;j++){ int x=0,y=0; for(i=1;i<=n;i++){ x+=p[i].d[j]; } for(i=1;i<=m;i++){ y+=p1[i].nu[j]; } if(x>y){ bj=true;break; } } if(bj){ printf("-1\n");continue; } bool bj1=false; for(int x=1;x<=k;x++){ SS=flow=cnt=star=0; memset(head,-1,sizeof(head)); for(i=1;i<=n;i++) SS+=p[i].d[x]; en=n+m+1; for(i=1;i<=m;++i) bu(star,i,p1[i].nu[x],0); for( i=1;i<=n;i++ ) for( j=1;j<=m;j++) bu(j,i+m,min(p[i].d[x],p1[j].nu[x]),p2[x].a[i][j]); for(i=1;i<=n;++i) bu(i+m,en,p[i].d[x],0); while(SPFA()); if(flow<SS) bj1=true; } if(bj1) puts("-1"); else printf("%d\n",cost); } }