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

最小费用最大网络流

时间:2018-05-10 21:47:23      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:+=   back   add   std   log   for   queue   space   void   

先贴一个dalao的链接

https://blog.csdn.net/stillxjy/article/details/52047189

其实我个人认为最大网络流就是在不断的尝试加入新的增广路

每条增广路都有一定的权值

每次找的增光路是权值最小的,所以凑出了最小费用

证明的话,我也不是很会,脑补出来感觉是对的

#include <iostream>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
const int maxn = 5005;
const int inf = 1e9;
struct edge
{
    int from,to,cost,c,f;
};
vector<edge> e;
vector<int> G[maxn];
void adde(int from,int to,int cost,int c,int f);
bool spfa(int s,int t,int &f,int &cost);
int main()
{
    int n,m,s,t;
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i =0 ; i < m; ++i)
    {
        int from,to,c,w;
        scanf("%d%d%d%d",&from,&to,&c,&w);
        adde(from, to, w, c, 0);
    }
    int flow=0,cost=0;
    while(spfa(s, t, flow,cost));
    printf("%d %d\n",flow,cost);
}
void adde(int from,int to,int cost,int c,int f)
{
    edge a;
    a.from = from;
    a.to = to;
    a.cost = cost;
    a.c = c;
    a.f = 0;
    e.push_back(a);
    swap(a.from,a.to);
    a.cost = -a.cost;
    a.c = 0;
    e.push_back(a);
    int cnt = e.size();
    G[from].push_back(cnt-2);
    G[to].push_back(cnt-1);
}
bool spfa(int s,int t,int &f,int &cost)
{
    int dis[maxn];
    bool inq[maxn];
    int p[maxn];
    int a[maxn];
    memset(inq, false, sizeof(inq));
    memset(a, 0, sizeof(a));
    memset(p, 0, sizeof(p));
    for(int i=0;i<maxn;++i)
    {
        dis[i] = inf;
    }
    queue<int> q;
    q.push(s);
    inq[s] = true;
    dis[s] = 0;
    a[s] = inf;
    while(!q.empty())
    {
        int u = q.front(),i;
        inq[u] = false;
        q.pop();
        for(i=0;i<G[u].size();++i)
        {
            edge l;
            l = e[G[u][i]];
            if(dis[l.to] > dis[u]+l.cost && l.c>l.f)
            {
                p[l.to] = G[u][i];
                a[l.to] = min(a[u],l.c - l.f);
                dis[l.to] = dis[u] + l.cost;
                if(!inq[l.to])
                {
                    inq[l.to] = true;
                    q.push(l.to);
                }
            }
        }
    }
    if(dis[t] == inf)
        return false;
    f += a[t];
    cost += a[t]*dis[t];
    int u = t;
    while(u != s)
    {
        e[p[u]].f += a[t];
        e[p[u]^1].f -= a[t];
        u = e[p[u]].from;
    }
    return true;
}

 

最小费用最大网络流

标签:+=   back   add   std   log   for   queue   space   void   

原文地址:https://www.cnblogs.com/mltang/p/9021693.html

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