zoukankan      html  css  js  c++  java
  • POJ-2516-Minimum Cost(网络流, 最小费用最大流)

    链接:

    https://vjudge.net/problem/POJ-2516

    题意:

    Dearboy, a goods victualer, now comes to a big problem, and he needs your help. In his sale area there are N shopkeepers (marked from 1 to N) which stocks goods from him.Dearboy has M supply places (marked from 1 to M), each provides K different kinds of goods (marked from 1 to K). Once shopkeepers order goods, Dearboy should arrange which supply place provide how much amount of goods to shopkeepers to cut down the total cost of transport.

    It's known that the cost to transport one unit goods for different kinds from different supply places to different shopkeepers may be different. Given each supply places' storage of K kinds of goods, N shopkeepers' order of K kinds of goods and the cost to transport goods for different kinds from different supply places to different shopkeepers, you should tell how to arrange the goods supply to minimize the total cost of transport.

    思路:

    建图, 但是不能对每个商品同时建图,每个商品矩阵分别建图,同时不满足条件就不要跑费用流了..会T.

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    //#include <memory.h>
    #include <queue>
    #include <set>
    #include <map>
    #include <algorithm>
    #include <math.h>
    #include <stack>
    #include <string>
    
    #define MINF 0x3f3f3f3f
    using namespace std;
    typedef long long LL;
    
    const int MAXN = 50+10;
    const int INF = 1e9;
    
    struct Edge
    {
        int from, to, flow, cap, cost;
        Edge(int from, int to, int flow, int cap, int cost)
        {
            this->from = from;
            this->to = to;
            this->flow = flow;
            this->cap = cap;
            this->cost = cost;
        }
    };
    
    vector<Edge> edges;
    vector<int> G[MAXN*MAXN*MAXN];
    int Sh[MAXN][MAXN];
    int Wo[MAXN][MAXN];
    int SumN[MAXN];
    int a[MAXN*MAXN];
    int Vis[MAXN*MAXN*MAXN], Dis[MAXN*MAXN*MAXN], Pre[MAXN*MAXN*MAXN];
    int n, m, k;
    int s, t;
    
    void AddEdge(int from, int to, int cap, int cost)
    {
        edges.push_back(Edge(from, to, 0, cap, cost));
        edges.push_back(Edge(to, from, 0, 0, -cost));
        int len = edges.size();
        G[from].push_back(len-2);
        G[to].push_back(len-1);
    }
    
    bool SPFA()
    {
        memset(Dis, MINF, sizeof(Dis));
        memset(Vis, 0, sizeof(Vis));
        queue<int> que;
        Dis[s] = 0;
        Vis[s] = 1;
        que.push(s);
        a[s] = INF;
        while (!que.empty())
        {
    //        for (int i = s;i <= t;i++)
    //            cout << Dis[i] << ' ' ;
    //        cout << endl;
            int u = que.front();
    //        cout << u << endl;
            que.pop();
            Vis[u] = 0;
            for (int i = 0;i < G[u].size();i++)
            {
                Edge &e = edges[G[u][i]];
                if (e.cap > e.flow && Dis[e.to] > Dis[u]+e.cost)
                {
                    Dis[e.to] = Dis[u]+e.cost;
                    Pre[e.to] = G[u][i];
                    a[e.to] = min(a[u], e.cap-e.flow);
                    if (!Vis[e.to])
                    {
                        que.push(e.to);
                        Vis[e.to] = 1;
                    }
                }
            }
        }
        if (Dis[t] != MINF)
            return true;
        return false;
    }
    
    int CostFlow(int &Flow)
    {
        int cost = 0;
        while (SPFA())
        {
    //        cout << 1 << endl;
    //        int Min = INF;
    //        for (int i = t;i != s;i = edges[Pre[i]].from)
    //            Min = min(Min, edges[Pre[i]].cap-edges[Pre[i]].flow);
    //        cout << Min << endl;
            for (int i = t;i != s;i = edges[Pre[i]].from)
            {
                edges[Pre[i]].flow += a[t];
                edges[Pre[i]^1].flow -= a[t];
    //            Edge &e = edges[Pre[i]], &ee = edges[Pre[i]^1];
    //            cout << e.from << ' ' << e.to << ' ' << e.flow << ' ' << e.cap << endl;
    //            cout << ee.from << ' ' << ee.to << ' ' << ee.flow << ' ' << ee.cap << endl;
    //            cout << endl;
            }
            cost += a[t]*Dis[t];
            Flow += a[t];
        }
        return cost;
    }
    
    void Init()
    {
        for (int i = 0;i <= n+m+1;i++)
            G[i].clear();
        edges.clear();
    }
    
    int main()
    {
    //    ios::sync_with_stdio(false);
    //    cin.tie(0);
        while (~scanf("%d %d %d", &n, &m, &k) && (n+m+k))
        {
            s = 0, t = n+m+1;
            for (int i = 1;i <= n;i++)
            {
                for (int j = 1;j <= k;j++)
                    scanf("%d", &Sh[i][j]);
            }
            memset(SumN, 0, sizeof(SumN));
            for (int i = 1;i <= m;i++)
            {
                for (int j = 1;j <= k;j++)
                    scanf("%d", &Wo[i][j]), SumN[j] += Wo[i][j];
            }
            int v;
            //shop = n*k
            //wo = n*k+m*k
            int res = 0, sumflow = 0;
            bool ok = true;
            for (int i = 1;i <= k;i++)
            {
                Init();
                int tmp = 0;
                for (int j = 1;j <= n;j++)
                {
                    AddEdge(s, j, Sh[j][i], 0);
                    tmp += Sh[j][i];
                }
                if (tmp > SumN[i])
                    ok = false;
                for (int j = 1;j <= n;j++)
                {
                    for (int z = 1;z <= m;z++)
                    {
                        scanf("%d", &v);
                        AddEdge(j, n+z, INF, v);
                    }
                }
                for (int j = 1;j <= m;j++)
                    AddEdge(n+j, t, Wo[j][i], 0);
                if (ok)
                    res += CostFlow(sumflow);
            }
            if (!ok)
                puts("-1");
            else
                printf("%d
    ", res);
        }
    
        return 0;
    }
    
  • 相关阅读:
    Python PEP8 编码规范中文版
    MySQL分区表
    mybatis缓存,包含一级缓存与二级缓存,包括ehcache二级缓存
    斐讯K2刷不死breed与第三方固件教程
    Mysql 多表连接查询 inner join 和 outer join 的使用
    mysql多表关联删除示例
    sublime Text 几款插件
    多进程vs多线程
    git 命令常用总结
    LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
  • 原文地址:https://www.cnblogs.com/YDDDD/p/11321810.html
Copyright © 2011-2022 走看看