网络流--最小费用最大流

最小费用最大流

求出一条最小费用边,然后对这条边增广,重复上述过程,直到没有到汇点的边
求最小费用边,用spfa()

#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 200100;
const int M = 1e9+7;
int n,m,s,t;

struct node
{
    int to,cost,dis,next;
}a[maxn];

int head[maxn],cnt = 2;

void add(int u,int v,int w,int f)
{
    a[cnt].to = v;a[cnt].cost = w;a[cnt].dis = f;
    a[cnt].next = head[u];head[u] = cnt;cnt++;
}


int dis[maxn];
bool vis[maxn];

int pre[maxn];      //前驱
int incf[maxn];      //当前路上的最小流

bool spfa()
{
    mem(dis,inf);mem(vis,0);
    dis[s] = 0;incf[s] = inf;
    queue<int> q;q.push(s);
    while(!q.empty())
    {   
        int u = q.front();q.pop();vis[u] = 0;
        for(int i = head[u];i; i = a[i].next)
        {   
            if(!a[i].cost) continue;
            int v = a[i].to;
            if(dis[v] > dis[u]+a[i].dis)
            {
                dis[v] = dis[u]+a[i].dis;

                incf[v] = min(incf[u],a[i].cost);
                pre[v] = i;

                if(!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
    if(dis[t] < inf) return 1;
    return 0;
}

int maxflow,mincost;

void mcff()
{
    while (spfa())
    {   
        maxflow += incf[t];
        mincost += dis[t]*incf[t];
        int x = t;
        while(x != s)
        {
            int i = pre[x];
            a[i].cost -= incf[t];
            a[i^1].cost += incf[t];
            x = a[i^1].to;
        }
    }
}

例题

https://www.luogu.com.cn/problem/P3381

猜你喜欢

转载自www.cnblogs.com/hezongdnf/p/12121301.html