题意:有N个客户,M个仓库,和K种货物。已知每个客户需要每种货物的数量,每个仓库存储每种货物的数量,每个仓库运输各种货物去各个客户的单位费用。判断所有的仓库能否满足所有客户的需求,如果可以,求出最少的运输总费用。
思路:最小费用最大流。先判断是否每种货物的存储总量都足够,足够的话,对每一种货物进行一次最小费用最大流求出完成这种货物运输的最小总费用,所有的总费用相加就是结果了。
思路:最小费用最大流。先判断是否每种货物的存储总量都足够,
足够的话,对每一种货物进行一次最小费用最大 流求出完成这种货物运输的最小总费用,所有的总费用相加就是结果了。
http://poj.org/problem?id=2516
1 #include<stdio.h> 2 #define maxn 200 3 #define inf 0x7fffffff 4 #include<string.h> 5 int need[maxn][maxn],needk[maxn],have[maxn][maxn],havek[maxn],cap[maxn][maxn],map[maxn][maxn]; 6 int que[maxn],ans,pre[maxn]; 7 int n,m,k,max; 8 int dis[maxn],vis[maxn]; 9 int min(int x,int y) 10 { 11 if(x<y)return x; 12 else return y; 13 } 14 int SPFA() 15 { 16 int i,head=0,tail=0; 17 for(i=0;i<=max;i++) 18 { 19 dis[i]=inf; 20 vis[i]=0; 21 } 22 dis[0]=0; 23 vis[0]=1; 24 que[head]=0; 25 tail++; 26 while(head!=tail) 27 { 28 29 int u=que[head]; 30 vis[u]=0; 31 for(i=0;i<=max;i++) 32 { 33 if(cap[u][i]&&dis[i]>dis[u]+map[u][i]) 34 { 35 36 dis[i]=dis[u]+map[u][i]; 37 pre[i]=u; 38 if(!vis[i]) 39 { 40 vis[i]=1; 41 que[tail++]=i; 42 if(tail==maxn)tail=0; 43 } 44 } 45 } 46 head++; 47 if(head==maxn)head=0; 48 } 49 if(dis[max]==inf)return 0; 50 else return 1; 51 } 52 void Update() 53 { 54 int i,sum=inf; 55 for(i=max;i!=0;i=pre[i]) 56 { 57 sum=min(sum,cap[pre[i]][i]);//寻找(最短)增广路经上的最小 流量 58 } 59 60 for(i=max;i!=0;i=pre[i]) 61 { 62 cap[pre[i]][i]-=sum; 63 cap[i][pre[i]]+=sum; 64 ans+=map[pre[i]][i]*sum; 65 66 } 67 68 } 69 int main() 70 { 71 int i,j,l; 72 while(scanf("%d%d%d",&n,&m,&k)!=EOF) 73 { 74 if(n==0&&m==0&&k==0)break; 75 memset(needk,0,sizeof(needk)); 76 memset(havek,0,sizeof(havek)); 77 for(i=1;i<=n;i++) 78 { 79 for(j=1;j<=k;j++) 80 { 81 scanf("%d",&need[i][j]); 82 needk[j]+=need[i][j]; 83 } 84 } 85 86 for(i=1;i<=m;i++) 87 { 88 for(j=1;j<=k;j++) 89 { 90 scanf("%d",&have[i][j]); 91 havek[j]+=have[i][j]; 92 } 93 } 94 int f=0; 95 ans=0; 96 for(i=1;i<=k;i++) 97 { 98 if(needk[i]>havek[i]) 99 { 100 f=1; 101 break; 102 } 103 } 104 105 max=n+m+1; 106 for(i=1;i<=k;i++) 107 { 108 memset(cap,0,sizeof(cap)); 109 for(j=1;j<=n;j++) 110 { 111 for(l=1;l<=m;l++) 112 { 113 scanf("%d",&map[l][j+m]); 114 map[j+m][l]=-map[l][j+m]; 115 cap[l][j+m]=inf; 116 117 } 118 } 119 120 for(j=1;j<=m;j++) 121 { 122 cap[0][j]=have[j][i]; 123 map[0][j]=map[j][0]=0; 124 125 } 126 for(j=1;j<=n;j++) 127 { 128 cap[j+m][max]=need[j][i]; 129 map[j+m][max]=map[max][j+m]=0; 130 } 131 132 while(SPFA())Update();//最小费用算法 133 134 } 135 if(!f)printf("%d\n",ans); 136 else printf("-1\n"); 137 } 138 }