zoukankan      html  css  js  c++  java
  • POJ2516 Minimum Cost

    这题的大意是有N个店主,有M个供应商,对于N个店主,每个主有一定的需求量(对应着K种商品),M个供应商也对应着一定的供应量。然后相应的供应是有一定的费用。最后问说是否能满足需求,不满足的话输出-1,满足的话输出最小的费用。模型是比较裸,这里对于每个商品,都建个图来费用流,相应的建个超级源点和超级汇点。每次spfa去找,复杂度是O(V*E*E)。

    感谢:

    http://www.cppblog.com/Icyflame/archive/2009/06/30/88891.html

    代码
    #include <iostream>
    #include
    <vector>
    #include
    <queue>
    using namespace std;

    const int MAX = 55;
    const int INF = INT_MAX;

    int N, M, K;
    int need[MAX][MAX];
    int give[MAX][MAX];
    int move[MAX][MAX][MAX];
    int SS, TT;
    int mm[2 * MAX][2 * MAX]; //flow map
    int cc[2 * MAX][2 * MAX]; //cost map
    int prev[2 * MAX];
    int flow[2 * MAX];
    int dis[2 * MAX];
    int in[2 * MAX];

    void ready()
    {
    for(int i = 1; i <= N; i++) for(int j = 1; j <= K; j++) scanf("%d", &need[i][j]);
    for(int i = 1; i <= M; i++) for(int j = 1; j <= K; j++) scanf("%d", &give[i][j]);
    for(int k = 1; k <= K; k++) for(int i = 1; i <= N; i++) for(int j = 1; j <= M; j++) scanf("%d", &move[k][i][j]);
    }

    void makeMap(int kind)
    {
    SS
    = 0, TT = N + M + 1;
    //make the flow map
    memset(mm, 0, sizeof(mm));
    for(int i = 1; i <= N; i++) mm[SS][i] = need[i][kind];
    for(int i = 1; i <= M; i++) mm[i + N][TT] = give[i][kind];
    for(int i = 1; i <= N; i++) for(int j = 1; j <= M; j++) mm[i][j + N] = need[i][kind];
    //make the cost map
    memset(cc, 0, sizeof(cc));
    for(int i = 1; i <= N; i++) for(int j = 1; j <= M; j++)
    {
    cc[i][j
    + N] = move[kind][i][j];
    cc[j
    + N][i] = -move[kind][i][j];
    }
    }

    int spfa()
    {
    memset(
    in, 0, sizeof(in));
    memset(dis,
    -1, sizeof(dis));
    memset(prev,
    -1, sizeof(prev));
    memset(flow,
    0, sizeof(flow));
    in[SS] = 1, dis[SS] = 0, flow[SS] = INF;
    vector
    <int> v;
    v.push_back(SS);
    for(int i = 0; i < v.size(); i++)
    {
    int u = v[i];
    in[u] = 0;
    for(int j = SS; j <= TT; j++)
    {
    if(mm[u][j] > 0 && (dis[j] == -1 || dis[u] + cc[u][j] < dis[j]))
    {
    dis[j]
    = dis[u] + cc[u][j];
    //in[j] = 1;
    prev[j] = u;
    flow[j]
    = min(flow[u], mm[u][j]);
    if(in[j] == 0) in[j] = 1, v.push_back(j);
    }
    }
    }
    return flow[TT];
    }

    int mcmf()
    {
    int res = 0;
    while(1)
    {
    int now = spfa();
    if(now == 0) break;
    int u = TT;
    while(u != SS)
    {
    int v = prev[u];
    mm[v][u]
    -= now;
    mm[u][v]
    += now;
    res
    += now * cc[v][u];
    u
    = v;
    }
    }
    for(int i = 1; i <= N; i++)
    {
    if(mm[SS][i] > 0) return -1;
    }
    return res;
    }

    int main()
    {
    while(scanf("%d%d%d", &N, &M, &K), N)
    {
    int res = 0;
    ready();
    for(int k = 1; k <= K; k++)
    {
    makeMap(k);
    int t = mcmf();
    if(t == -1)
    {
    res
    = -1;
    break;
    }
    res
    += t;
    }
    printf(
    "%d\n", res);
    }
    }
  • 相关阅读:
    UI设计学习路径(一个)—好酒也怕巷子深
    shell script 入门 笔记
    HDU 4864Task(更多的联合培训学校1)(贪婪)
    XCL-Charts绘画面积图(AreaChart) 例1
    table插入标签form标记怪现象
    ECharts SSH+JQueryAjax+Json+JSP在数据库中的数据来填充ECharts在
    Xcode 6 AutoLayout Size Classes
    POJ 1984 Navigation Nightmare (数据结构-并检查集合)
    DataTable填补了实体类返回泛型集合
    Cisco C2900XL
  • 原文地址:https://www.cnblogs.com/litstrong/p/1795277.html
Copyright © 2011-2022 走看看