• 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
    ", mincost);
    118         else puts("-1");
    119     }
    120     return 0;
    121 }
  • 相关阅读:
    论信息系统项目沟通管理
    程序员到底怎么了
    Spring DBCP用xml和properties2种格式配置DataSource
    Spring Aop的理解和简单实现
    数据库常见面试题总结
    java常见面试题总结
    【JavaEE】企业面试问题-Java基础
    Java String常见面试题汇总
    JavaScript事件详解
    JavaScript函数使用技巧
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6235460.html
Copyright © 2020-2023  润新知