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

    题意:

    从发货地到商家 送货 求送货花费的最小费用。。。

    有m个发货地,,,n个商家,,每个商家所需要的物品和物品的个数都不一样,,,每个发货地有的物品和物品的个数也不一样,,,

    从不同的发货地到不同的商家 送不同的物品 所花费的价钱 也不一样。。

    解析;

    建立超级源s和超级汇t

    因为每个商家所需的每个物品的数量都不一样,,,所以我们要分物品来进行最小费用最大流

    在最外面一个循环,遍历每一个物品,,,然后对于当前物品建图

    把每个发货地和s连边 权值为每个发货地所拥有的当前物品的数量,,,花费0

    把商家个t连边,, 权值为每个商家所需要的当前物品的数量,,花费0

    然后 发货地和商家连边。。。权值为INF,  花费为每个发货地到每个商家对于当前物品所对应的花费

    这是一个对象所需不同物品的个数不一样的题

    贴一个对象所需不同物品的个数一样的题:https://www.cnblogs.com/WTSRUVF/p/9202751.html

    代码如下:

    #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
    ");
                    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;
    }
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    CSS之各种居中
    三步教会你装系统
    65条最常用正则表达式
    MongoDB介绍
    MongoDB基本命令用
    log4j配置
    使用spring + ActiveMQ 总结
    log4j配置文件
    如何入侵局域网电脑
    目标检测的图像特征提取
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9228574.html
Copyright © 2011-2022 走看看