码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 6118 度度熊的交易计划 最大费用可行流

时间:2017-08-16 20:21:02      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:ons   class   print   计划   商品   show   include   spfa   最大流   

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6118

题意:中文题

分析:

最小费用最大流,首先建立源点 s ,与超级汇点 t 。因为生产一个商品需要花费 a[i] 元,且上限为 b[i] ,所以我们从 s 向这些点之间连一条容量为 b[i] ,费用为 a[i] 的边。同样的道理,出售一个商品可以赚到 c[i] 元,最多出售 d[i] 个,于是我们从这些点向 t 连一条容量为 d[i] ,费用为 -c[i] 的边。最后所有的公路也是花费,从 uv 连接一条双向边,容量为 INF ,费用为 k,然而要注意这道题并不是要求最大流,这道题要求的是可行流,这个只需要修改一下求增广的过程就可以了,最后答案就是费用流的相反数。

 

#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3FFFFFFF;
const int maxn = 2222;
struct node{
    int st, en, flow, cost, next;
    node(){}
    node(int st, int en, int flow, int cost, int next):st(st),en(en),flow(flow),cost(cost),next(next){}
}E[101000];

int num, p[maxn];
void init(){
    memset(p, -1, sizeof(p));
    num = 0;
}
void add(int st, int en, int flow, int cost){
    E[num] = node(st, en, flow, cost, p[st]);
    p[st] = num++;
    E[num] = node(en, st, 0, -cost, p[en]);
    p[en] = num++;
}
int pre[maxn];
int dis[maxn];
bool fg[maxn];
bool spfa(int st, int en)
{
    for(int i=0;i<=en;i++){
        fg[i] = 0, dis[i] = inf, pre[i]=-1;
    }
    queue<int>q;
    q.push(st);
    fg[st]=1;
    dis[st]=0;
    while(!q.empty()){
        int u = q.front(); q.pop();
        fg[u]=0;
        for(int i=p[u];~i;i=E[i].next){
            int v = E[i].en;
            if(E[i].flow&&dis[v]>dis[u]+E[i].cost){
                dis[v] = dis[u]+E[i].cost;
                pre[v]=i;
                if(!fg[v]){
                    fg[v]=1;
                    q.push(v);
                }
            }
        }
    }
//    if(dis[en] < inf) return 1;
//    return 0;
    return dis[en]<=0;
}

int solve(int st, int en){
    int ans=0;
    while(spfa(st,en)){
        int d = inf;
        for(int i=pre[en];i+1;i=pre[E[i].st]) d = min(d, E[i].flow);
        for(int i=pre[en];i+1;i=pre[E[i].st]){
            E[i].flow -= d;
            E[i^1].flow += d;
            ans += d*E[i].cost;
        }
    }
    return ans;
}
int main()
{
    int n,m;
    while (cin>>n>>m)
    {
        init();
        int s=0,t=n+1,cost;
        for (int i=1; i<=n; i++)
        {
            int a,b,c,d;
            cin>>a>>b>>c>>d;
            add(s,i,b,a);
            add(i,t,d,-c);
        }
        while (m--)
        {
            int u,v,k;
            cin>>u>>v>>k;
            add(u,v,inf,k);
            add(v,u,inf,k);
        }
        int ans = -solve(s,t);
        printf("%d\n", ans);
    }
    return 0;
}

 

HDU 6118 度度熊的交易计划 最大费用可行流

标签:ons   class   print   计划   商品   show   include   spfa   最大流   

原文地址:http://www.cnblogs.com/spfa/p/7375229.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!