1. 程式人生 > 其它 >POJ-2516 Minimum Cost

POJ-2516 Minimum Cost

最小費用最大流

題意:有k種商品,m家供貨商,n位顧客。給出每家供貨商每種商品的貨源,每位顧客對每種商品的需求,每種商品在每對供給中的運費,求每位顧客的要求都能滿足時的最小運費。如果無法滿足顧客要求,輸出-1.

解:對每種商品跑最小費用最大流,然後加上每次的最小費用。如果最大流比顧客需求小,輸出-1。建立源點,流向供給商,邊權為貨源數量;供給商向每位顧客連邊,邊權為貨源數量和運費;顧客向聚點連邊,邊權為需求,然後跑板子。板子因為inf大小不一樣,調了好久。

程式碼:

  1 #include <stdio.h>
  2 #include <algorithm>
  3 #include <queue>
  4
using namespace std; 5 #define maxx 1000005 6 #define maxm 100005 7 #define maxn 5005 8 #define inf 0x3f3f3f3f 9 #define ll long long 10 int n,m,k; 11 int a[55][55],b[55][55],c[55][55][55]; 12 13 int head[maxn],cnt; 14 struct Edge{ 15 int v,w,next,flow; 16 }edge[maxm]; 17 int s,t; 18 int
dis[maxn],incf[maxn],pre[maxn],inque[maxn]; 19 int maxflow,mincost; 20 void init(){ 21 memset(head,-1,sizeof(head)); 22 maxflow=mincost=0; 23 cnt=0; 24 } 25 void add(int u,int v,int flow,int cost){ 26 edge[cnt].w=cost; 27 edge[cnt].v=v; 28 edge[cnt].flow=flow; 29 edge[cnt].next=head[u];
30 head[u]=cnt++; 31 } 32 void addEdge(int u,int v,int flow,int cost){ 33 add(u,v,flow,cost); 34 add(v,u,0,-cost); 35 } 36 int spfa(){ 37 queue<int>q; 38 memset(dis,0x3f,sizeof(dis)); 39 memset(inque,0,sizeof(inque)); 40 q.push(s); dis[s]=0; inque[s]=1; incf[s]=inf; 41 while(!q.empty()){ 42 int u=q.front();q.pop(); 43 inque[u]=0; 44 for(int i=head[u];~i;i=edge[i].next){ 45 if(!edge[i].flow) continue; 46 int v=edge[i].v; 47 if(dis[v]>dis[u]+edge[i].w){ 48 dis[v]=dis[u]+edge[i].w; 49 incf[v]=min(incf[u],edge[i].flow); 50 pre[v]=i; 51 if(!inque[v]){ 52 q.push(v); 53 inque[v]=1; 54 } 55 } 56 } 57 } 58 if(dis[t]==inf) 59 return 0; 60 return 1; 61 } 62 void MCMF(){ 63 while(spfa()){ 64 int x=t; 65 maxflow+=incf[t]; 66 mincost+=dis[t]*incf[t]; 67 int i; 68 while(x!=s){ 69 i=pre[x]; 70 edge[i].flow-=incf[t]; 71 edge[i^1].flow+=incf[t]; 72 x=edge[i^1].v; 73 } 74 } 75 } 76 77 signed main(){ 78 while(~scanf("%d%d%d",&n,&m,&k)) { 79 if(n==0&&m==0&&k==0) 80 break; 81 s=n+m+5,t=s+1; 82 for(int i=1;i<=n;i++) 83 for(int j=1;j<=k;j++) 84 scanf("%d",&a[i][j]); 85 for(int i=1;i<=m;i++) 86 for(int j=1;j<=k;j++) 87 scanf("%d",&b[i][j]); 88 for(int l=1;l<=k;l++) 89 for(int i=1;i<=n;i++) 90 for(int j=1;j<=m;j++) 91 scanf("%d",&c[l][i][j]); 92 int ans=0; 93 for(int l=1;l<=k;l++){ 94 int need=0; 95 init(); 96 for(int i=1;i<=n;i++) 97 addEdge(i,t,a[i][l],0),need+=a[i][l]; 98 for(int i=1;i<=m;i++) 99 addEdge(s,i+n,b[i][l],0); 100 for(int i=1;i<=n;i++) 101 for(int j=1;j<=m;j++) 102 addEdge(j+n,i,b[j][l],c[l][i][j]); 103 MCMF(); 104 if(maxflow<need){ 105 ans=-1; 106 break; 107 } 108 else 109 ans+=mincost; 110 } 111 printf("%d\n",ans); 112 } 113 return 0; 114 }
View Code