1. 程式人生 > >Minimum Cost POJ - 2516(模板題。。沒啥好說的。。)

Minimum Cost POJ - 2516(模板題。。沒啥好說的。。)

stream node ios sizeof UC truct AD 個數 div

題意:

從發貨地到商家 送貨 求送貨花費的最小費用。。。

有m個發貨地,,,n個商家,,每個商家所需要的物品和物品的個數都不一樣,,,每個發貨地有的物品和物品的個數也不一樣,,,

從不同的發貨地到不同的商家 送不同的物品 所花費的價錢 也不一樣。。

解析;

建立超級源s和超級匯t

因為每個商家所需的每個物品的數量都不一樣,,,所以我們要分物品來進行最小費用最大流

在最外面一個循環,遍歷每一個物品,,,然後對於當前物品建圖

把每個發貨地和s連邊 權值為每個發貨地所擁有的當前物品的數量,,,花費0

把商家個t連邊,, 權值為每個商家所需要的當前物品的數量,,花費0

然後 發貨地和商家連邊。。。權值為INF, 花費為每個發貨地到每個商家對於當前物品所對應的花費

代碼如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn = 100100, INF = 0x7fffffff;
typedef long long LL;
int head[maxn], d[maxn], vis[maxn], p[maxn], f[maxn];
int frome[maxn], to[maxn], ca[55][55][55]; int needs[55][55], have[55][55]; int n, m, s, t, k; int cnt, flow, value; struct node{ int u, v, c, w, next; }Node[maxn]; void add_(int u, int v, int c, int w) { Node[cnt].u = u; Node[cnt].v = v; Node[cnt].c = c; Node[cnt].w = w; Node[cnt].next
= head[u]; head[u] = cnt++; } void add(int u, int v, int c, int w) { add_(u, v, c, w); add_(v, u, 0 ,-w); } int spfa() { queue<int> Q; for(int i=0; i<maxn; i++) d[i] = INF; mem(vis, 0); mem(p, -1); Q.push(s); d[s] = 0; vis[s] = 1; p[s] = 0; f[s] = INF; while(!Q.empty()) { int u = Q.front(); Q.pop(); vis[u] = 0; for(int i=head[u]; i!=-1; i=Node[i].next) { node e = Node[i]; if(d[e.v] > d[e.u] + e.w && e.c > 0) { d[e.v] = d[e.u] + e.w; p[e.v] = i; f[e.v] = min(f[u], e.c); if(!vis[e.v]) { Q.push(e.v); vis[e.v] = 1; } } } } if(p[t] == -1) return 0; flow += f[t]; value += f[t]* d[t]; for(int i=t; i!=s; i=Node[p[i]].u) { Node[p[i]].c -= f[t]; Node[p[i]^1].c += f[t]; } return 1; } int max_flow() { value = 0; flow = 0; while(spfa()); return value; } int main() { while(~scanf("%d%d%d",&n,&m,&k) && n+m+k) { int ret = 0; int ok = 1; s = 0, t = (n+m)*2+10; mem(head, -1); mem(frome, 0); mem(to, 0); cnt = 0; for(int i=1; i<=n; i++) for(int j=1; j<=k; j++) { scanf("%d",&needs[i][j]); frome[j] += needs[i][j]; } for(int i=1; i<=m; i++) for(int j=1; j<=k; j++) { scanf("%d",&have[i][j]); to[j] += 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",&ca[i][j][l]); for(int i=1; i<=k; i++) { if(frome[i] > to[i]) { printf("-1\n"); ok = 0; break; } } if(!ok) continue; for(int i=1; i<=k; i++) { mem(head, -1); cnt = 0; for(int j=1; j<=n; j++) add(j, t, needs[j][i], 0); for(int j=1; j<=m; j++) add(s, n+j, have[j][i], 0); for(int j=1; j<=m; j++) for(int l=1; l<=n; l++) add(n+j, l, INF, ca[i][l][j]); ret += max_flow(); } cout<< ret <<endl; } return 0; }

Minimum Cost POJ - 2516(模板題。。沒啥好說的。。)