HDU 6188最小费用流

Posted 卷珠帘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 6188最小费用流相关的知识,希望对你有一定的参考价值。

题目链接:http://hdu.hustoj.com/showproblem.php?pid=6118

掉坑里了,图很好建,Wa了一发,看了Disscuss里面有人提供了一组样例,画图发现:最小流模板是在满足最大流情况下的最小费用,而本题目不需要满足最大流直接求最小费用。注意一下。

/*
5 4
1 2 1 2
2 1 2 1
2 3 4 5
5 4 3 2
100 1 1 1
1 2 1
2 3 1
3 4 1
1 5 1
*/

应该输出8的。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 4e3;
const int INF = 1e9;
int dist[maxn];
int tot,head[maxn];
int pv[maxn],pe[maxn];
struct edge
{
    int to,pre,cap,cost;
}e[20000];
typedef pair<int,int> P;
void init()
{
    tot = 0;
    memset(head,-1,sizeof(head));
}
void add(int from,int to,int cap,int cost)
{
    e[tot].pre = head[from];
    e[tot].to = to;
    e[tot].cap = cap;
    e[tot].cost = cost;
    head[from] = tot++;
}
void addedge(int from,int to,int cap,int cost)
{
    add(from,to,cap,cost);
    add(to,from,0,-cost);
}
int ans = 10000000;
int min_cost_flow(int s,int t,int f,int& max_flow)
{
    int ret = 0;
    while(f>0)
    {
        priority_queue<P,vector<P>,greater<P> >q;
        for(int i=0;i<maxn;i++) dist[i] = INF;
        dist[s] = 0;
        q.push(P(0,s));
        while(!q.empty())
        {
            P cur = q.top(); q.pop();
            int v = cur.second;
            if(dist[v]<cur.first) continue;
            for(int i=head[v];i>=0;i=e[i].pre)
            {
                int to = e[i].to,cap = e[i].cap,cost = e[i].cost;
                if(cap>0&&dist[to]>dist[v]+cost)
                {
                    pv[to] = v,pe[to] = i;
                    dist[to] = dist[v] + cost;
                    q.push(P(dist[to],to));
                }
            }
        }
        if(dist[t]==INF) return ret;
        ///当所有边的流量都流净后,即没有残余网络,返回。
        int d = f;
        for(int v=t;v!=s;v=pv[v])
        {
            d = min(d,e[pe[v]].cap);
        }
        f -= d;
        max_flow += d;
        ans = min(ans,ret);
        ret += d*dist[t]; ///走一单位就消耗dist[t]
        for(int v=t;v!=s;v=pv[v])
        {
            e[pe[v]].cap -= d;
            e[pe[v]^1].cap += d;
        }
    }
    return ret;
}
int a[maxn],b[maxn],c[maxn],d[maxn];
int main()
{
    int n,m;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        int s=0,t=3500;
        init(); //别忘写
        for(int i=1;i<=n;i++)
        {
            scanf("%d %d %d %d",&a[i],&b[i],&c[i],&d[i]);
        }
        for(int i=1;i<=n;i++)
        {
            addedge(s,i,b[i],a[i]);
            addedge(i,t,d[i],-c[i]);
        }
        for(int i=1;i<=m;i++)
        {
            int u,v,k;
            scanf("%d %d %d",&u,&v,&k);
            addedge(u,v,INF,k);
            addedge(v,u,INF,k);
        }
        int maxflow = 0;
        ans = 10000000;
        min_cost_flow(s,t,INF,maxflow);
        if(ans>=0) printf("0\n");
        else printf("%d\n",-ans);
    }
    return 0;
}
/*
5 4
1 2 1 2
2 1 2 1
2 3 4 5
5 4 3 2
100 1 1 1
1 2 1
2 3 1
3 4 1
1 5 1
*/

 

以上是关于HDU 6188最小费用流的主要内容,如果未能解决你的问题,请参考以下文章

HDU 6118 度度熊的交易计划 (最小费用流)

HDU 3435A new Graph Game(网络流之最小费用流)

HDU 4807Lunch Time 最小费用最大流

HDU 1533 最小费用最大流(模板)

HDU4411 最小费用流

HDU1533 最小费用最大流