POJ 2516:Minimum Cost(最小费用流)

Posted Shadowdsp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2516:Minimum Cost(最小费用流)相关的知识,希望对你有一定的参考价值。

https://vjudge.net/problem/11079/origin

题意:有N个商店和M个供应商和K种物品,每个商店每种物品有一个需求数,每个供应商每种物品有一个供应量,供应商到商店之间的运输需要花费,如果供不应求输出-1,否则输出最小花费。

思路:比较明显的最小费用流。想法大概都是源点和供应商连一条容量为供应量,花费为0的边,商店和汇点之间连一条容量为需求量,花费为0的边,供应商和商店之间连一条容量为INF,花费为题意给出的花费的边。建图的话一开始是直接对于每一个商店每一种物品和每一个供应商每一种物品都看做一个点,这样的点数是n*k+m*k+两个源点,超级大的图,就TLE了。看了下别人的思路,每一种商品是独立的,那么对于每一种商品建一次图,这样的点数是n + m + 两个源点,然后跑 k 次。优化了N多。。。。太菜鸡了。。。。还有数组开的不能太小,开55的时候TLE,105就AC了。

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <cstring>
  5 #include <string>
  6 #include <cmath>
  7 #include <queue>
  8 #include <vector>
  9 #include <map>
 10 #include <set>
 11 using namespace std;
 12 #define INF 0x3f3f3f3f
 13 #define N 105
 14 typedef long long LL;
 15 struct Edge {
 16     int u, v, cap, cost;
 17     Edge () {}
 18     Edge (int u, int v, int cap, int cost) : u(u), v(v), cap(cap), cost(cost) {}
 19 } edge[N*N];
 20 int tot, pre[N], vis[N], dis[N], S, T;
 21 int shop[N][N], sup[N][N], tolshop[N], tolsup[N], cost[N][N][N];
 22 vector<int> G[N];
 23 void Add(int u, int v, int cap, int cost) {
 24     edge[tot] = Edge(u, v, cap, cost);
 25     G[u].push_back(tot++);
 26     edge[tot] = Edge(v, u, 0, -cost);
 27     G[v].push_back(tot++);
 28 }
 29 
 30 int SPFA() {
 31     queue<int> que;
 32 //    puts("SPFA");
 33     memset(dis, INF, sizeof(dis));
 34     memset(vis, 0, sizeof(vis));
 35     dis[S] = 0; que.push(S);
 36     vis[S] = 1;
 37     while(!que.empty()) {
 38         int u = que.front(); que.pop();
 39         vis[u] = 0;
 40         for(int i = 0; i < G[u].size(); i++) {
 41             Edge& e = edge[G[u][i]];
 42             if(dis[u] + e.cost < dis[e.v] && e.cap > 0) { // 先松弛在判断是否在队里
 43                 dis[e.v] = dis[u] + e.cost;
 44                 pre[e.v] = G[u][i];
 45                 if(vis[e.v]) continue;
 46                 que.push(e.v);
 47                 vis[e.v] = 1;
 48             }
 49         }
 50     }
 51     return dis[T] < INF;
 52 }
 53 
 54 void MFMC(int &maxflow, int &cost) {
 55     int u = T, flow = INF;
 56     while(u != S) {
 57         Edge& e = edge[pre[u]];
 58         if(e.cap < flow) flow = e.cap;
 59         u = e.u;
 60     } u = T;
 61     while(u != S) {
 62         Edge& e1 = edge[pre[u]];
 63         Edge& e2 = edge[pre[u]^1];
 64         e1.cap -= flow; e2.cap += flow;
 65         cost += flow * e1.cost;
 66         u = e1.u;
 67     }
 68     maxflow += flow;
 69 }
 70 
 71 int main() {
 72     int n, m, k;
 73     while(~scanf("%d%d%d", &n, &m, &k), n + m + k) {
 74         S = 0; T = n + m + 1;
 75         memset(tolsup, 0, sizeof(tolsup));
 76         memset(tolshop, 0, sizeof(tolshop));
 77         for(int i = 1; i <= n; i++) {
 78             for(int j = 1; j <= k; j++) {
 79                 scanf("%d", &shop[i][j]);
 80                 tolshop[j] += shop[i][j];
 81             }
 82         }
 83         for(int i = 1; i <= m; i++) {
 84             for(int j = 1; j <= k; j++) {
 85                 scanf("%d", &sup[i][j]);
 86                 tolsup[j] += sup[i][j];
 87             }
 88         }
 89         for(int x = 1; x <= k; x++) {
 90             for(int i = 1; i <= n; i++) {
 91                 for(int j = 1; j <= m; j++) {
 92                     scanf("%d", &cost[x][i][j]);
 93                 }
 94             }
 95         }
 96         int flag = 1;
 97         int maxflow = 0, mincost = 0;
 98         for(int x = 1; x <= k; x++) {
 99             if(tolshop[x] > tolsup[x]) {
100                 flag = 0; break;
101             }
102             tot = 0;
103             for(int i = S; i <= T; i++) G[i].clear();
104             for(int i = 1; i <= n; i++) {
105                 Add(i, T, shop[i][x], 0);
106             }
107             for(int i = 1; i <= m; i++) {
108                 Add(S, i + n, sup[i][x], 0);
109             }
110             for(int i = 1; i <= n; i++) {
111                 for(int j = 1; j <= m; j++) {
112                     Add(j + n, i, sup[j][x], cost[x][i][j]);
113                 }
114             }
115             while(SPFA()) MFMC(maxflow, mincost);
116         }
117         if(flag) printf("%d\n", mincost);
118         else puts("-1");
119     }
120     return 0;
121 }

 

以上是关于POJ 2516:Minimum Cost(最小费用流)的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2516 Minimum Cost (最小费用最大流)

POJ2516 Minimum Cost最小费用最大流

POJ 2516:Minimum Cost(最小费用流)

POJ2516Minimum Cost

Minimum Cost POJ - 2516 (模板题 spfa最小费用最大流)

POJ-2516 Minimum Cost(最小费用最大流)