洛谷_3381 最小费用最大流

题意

给出一个网络,每条边有一个单位费用,如果一条边的单位费用是w,流的量是v,那么这里的费用就是w*v。求出它在最大流的情况下需要的最小费用。

思路

这里用的是ford-fulkerson算法。我们首先按照单位费用来找最短路,因为可能有负边权,所以我这里用的是SPFA。然后用ford-fulkerson算法给每条路更新流量和计算答案。

代码

#include<cstring>
#include<cstdio>
#include<queue>
#define min(a,b) a<b?a:b
using namespace std;
int tot,ans2,ans1,n,m,s,t,ui,vi,wi,fi,head[5001],dis[5001],pre[5001],v[5001];
struct node{
    int x,y,next,cost,flow;
    //cost代表单位费用,flow代表剩余流量
}e[100001];
void add(int x,int y,int l,int f)
{
    e[++tot].x=x;
    e[tot].y=y;
    e[tot].cost=f;
    e[tot].flow=l;
    e[tot].next=head[x];
    head[x]=tot;

    e[++tot].x=y;
    e[tot].y=x;
    e[tot].cost=-f;
    e[tot].flow=0;
    e[tot].next=head[y];
    head[y]=tot;
}
bool spfa()
{
    queue<int> q;
    int x,y;
    for (int i=0;i<=n;i++)  
    {
        dis[i]=2147483647;
        v[i]=0;
    }
    q.push(s);dis[s]=0;v[s]=1;
    while (q.size())
    {
        x=q.front();q.pop();v[x]=0;
        for (int i=head[x];~i;i=e[i].next)
        {
            if (!e[i].flow) continue;
            y=e[i].y;
            if (dis[y]>dis[x]+e[i].cost)
            {
                dis[y]=dis[x]+e[i].cost;//以单位费用做最短路
                pre[y]=i;//记录是从哪个点过来的
                if (!v[y])
                {
                    v[y]=1;
                    q.push(y);
                }
            }
        }
    }
    return dis[t]<2147483647;
}
void addflow()
{
    int i=t,mn=2147483647;
    while (pre[i])
    {
        mn=min(mn,e[pre[i]].flow);//找到这条路径上最小的流量
        i=e[pre[i]].x;//一直遍历这条路径上的点
    }
    ans1+=mn;//最大流ans2+=dis[t]*mn;//总费用等于流量*单位费用
    i=t;
    while (pre[i])
    {
        e[pre[i]].flow-=mn;//正向边的剩余流量减了
        e[pre[i]^1].flow+=mn;//逆向边的流量就加了
        i=e[pre[i]].x;
    }
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&t);
    tot=1;
    memset(head,-1,sizeof(head));
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d%d%d",&ui,&vi,&wi,&fi);
        add(ui,vi,wi,fi);
    }
    while (spfa())//如果源点可以到达汇点
        addflow();//我们就一直更新
    printf("%d %d",ans1,ans2);
}

猜你喜欢

转载自blog.csdn.net/ssl_hzb/article/details/80770799
今日推荐