zoukankan      html  css  js  c++  java
  • hdu 6118度度熊的交易计划(费用流)

    度度熊的交易计划

    Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1192    Accepted Submission(s): 440


    Problem Description
    度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题:

    喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区。

    由于生产能力的区别,第i个片区能够花费a[i]元生产1个商品,但是最多生产b[i]个。

    同样的,由于每个片区的购买能力的区别,第i个片区也能够以c[i]的价格出售最多d[i]个物品。

    由于这些因素,度度熊觉得只有合理的调动物品,才能获得最大的利益。

    据测算,每一个商品运输1公里,将会花费1元。

    那么喵哈哈村最多能够实现多少盈利呢?
     
    Input
    本题包含若干组测试数据。
    每组测试数据包含:
    第一行两个整数n,m表示喵哈哈村由n个片区、m条街道。
    接下来n行,每行四个整数a[i],b[i],c[i],d[i]表示的第i个地区,能够以a[i]的价格生产,最多生产b[i]个,以c[i]的价格出售,最多出售d[i]个。
    接下来m行,每行三个整数,u[i],v[i],k[i],表示该条公路连接u[i],v[i]两个片区,距离为k[i]

    可能存在重边,也可能存在自环。

    满足:
    1<=n<=500,
    1<=m<=1000,
    1<=a[i],b[i],c[i],d[i],k[i]<=1000,
    1<=u[i],v[i]<=n
     
    Output
    输出最多能赚多少钱。
     
    Sample Input
    2 1 5 5 6 1 3 5 7 7 1 2 1
     
    Sample Output
    23
     
    题解:建边
    1.建立超级源点S,对每个片区i连容量为b[i],费用为a[i]的单向边.
    2.每个片区对可达的片区连容量为正无穷,费用为距离k[i]的双向边.
    3.每个片区对汇点T连容量为d[i],费用为c[i]的双向边.
    但是这样跑出来的是最大流下的最小费用.我们需要的是最小费用,所以当增广路 >=0(即没有比0小的增广路可以进行增广了),直接退出,取反最小费用,即是能赚的最多的钱.
    #include <iostream>
    #include <algorithm>
    #include <stdio.h>
    #include <string.h>
    #include <queue>
    using namespace std;
    
    const int INF = 999999999;
    const int N = 600;
    const int M = 200005;
    struct Edge{
        int u,v,cap,cost,next;
    }edge[M];
    int head[N],tot,low[N],pre[N];
    int total;
    bool vis[N];
    void addEdge(int u,int v,int cap,int cost,int &k){
        edge[k].u=u,edge[k].v=v,edge[k].cap = cap,edge[k].cost = cost,edge[k].next = head[u],head[u] = k++;
        edge[k].u=v,edge[k].v=u,edge[k].cap = 0,edge[k].cost = -cost,edge[k].next = head[v],head[v] = k++;
    }
    void init(){
        memset(head,-1,sizeof(head));
        tot = 0;
    }
    bool spfa(int s,int t,int n){
        memset(vis,false,sizeof(vis));
        for(int i=0;i<=n;i++){
            low[i] = (i==s)?0:INF;
            pre[i] = -1;
        }
        queue<int> q;
        q.push(s);
        while(!q.empty()){
            int u = q.front();
            q.pop();
            vis[u] = false;
            for(int k=head[u];k!=-1;k=edge[k].next){
                int v = edge[k].v;
                if(edge[k].cap>0&&low[v]>low[u]+edge[k].cost){
                    low[v] = low[u] + edge[k].cost;
                    pre[v] = k; ///v为终点对应的边
                    if(!vis[v]){
                        vis[v] = true;
                        q.push(v);
                    }
                }
            }
        }
        if(pre[t]==-1) return false;
        return true;
    }
    int MCMF(int s,int t,int n){
        int mincost = 0,minflow,flow=0;
         while(spfa(s,t,n))
        {
            if(low[t]>=0) break;
            minflow=INF+1;
            for(int i=pre[t];i!=-1;i=pre[edge[i].u])
                minflow=min(minflow,edge[i].cap);
            flow+=minflow;
            for(int i=pre[t];i!=-1;i=pre[edge[i].u])
            {
                edge[i].cap-=minflow;
                edge[i^1].cap+=minflow;
            }
            mincost+=low[t]*minflow;
        }
        total=flow;
        return mincost;
    }
    
    int main()
    {
        int n,m,h,tcase;
        while(scanf("%d%d",&n,&m)!=EOF){
    
            init();
            int s = 0,t = n+1;
            for(int i=1;i<=n;i++){
                //if(a[i]>=mx) b[i] = 0;
                int a,b,c,d;
                scanf("%d%d%d%d",&a,&b,&c,&d);
                addEdge(s,i,b,a,tot);
                addEdge(i,t,d,-c,tot);
            }
            for(int i=1;i<=m;i++){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                addEdge(u,v,INF,w,tot);
                addEdge(v,u,INF,w,tot);
            }
            long long ans = MCMF(s,t,n+1);
            cout<<-ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    在Leangoo里怎么添加,移动列表,修改列表名称?
    在Leangoo里怎么列表示例,插入列表?
    tomcat如何按站点调试本机程序
    ORA-12519, TNS:no appropriate service handler found
    mysql 远程访问
    手机端调试成功笔记
    Cannot find class for bean with name service
    android模拟器不能用键盘
    eclipse使用基础--让toolbar显示自己想要的内容
    mysql解压版安装
  • 原文地址:https://www.cnblogs.com/liyinggang/p/7454167.html
Copyright © 2011-2022 走看看