最小费用最大流

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
namespace MCMF
{
const int MAXN = 10000, MAXM = 10000, INF = 0x7fffffff;
int head[MAXN], cnt = 1;
struct Edge
{
    int to, w, c, next;
} edges[30000000];
inline void add(int from, int to, int w, int c)
{
    edges[++cnt] = {to, w, c, head[from]};
    head[from] = cnt;
}
inline void addEdge(int from, int to, int w, int c)
{
    add(from, to, w, c);
    add(to, from, 0, -c);
}
int s, t, dis[MAXN], cur[MAXN];
bool inq[MAXN], vis[MAXN];
queue<int> Q;
bool SPFA()
{
    while (!Q.empty())
        Q.pop();
    copy(head, head + MAXN, cur);
    fill(dis, dis + MAXN, INF);
    dis[s] = 0;
    Q.push(s);
    while (!Q.empty())
    {
        int p = Q.front();
        Q.pop();
        inq[p] = 0;
        for (int e = head[p]; e != 0; e = edges[e].next)
        {
            int to = edges[e].to, vol = edges[e].w;
            if (vol > 0 && dis[to] > dis[p] + edges[e].c)
            {
                dis[to] = dis[p] + edges[e].c;
                if (!inq[to])
                {
                    Q.push(to);
                    inq[to] = 1;
                }
            }
        }
    }
    return dis[t] != INF;
}
int dfs(int p = s, int flow = INF)
{
    if (p == t)
        return flow;
    vis[p] = 1;
    int rmn = flow;
    for (int eg = cur[p]; eg && rmn; eg = edges[eg].next)
    {
        cur[p] = eg;
        int to = edges[eg].to, vol = edges[eg].w;
        if (vol > 0 && !vis[to] && dis[to] == dis[p] + edges[eg].c)
        {
            int c = dfs(to, min(vol, rmn));
            rmn -= c;
            edges[eg].w -= c;
            edges[eg ^ 1].w += c;
        }
    }
    vis[p] = 0;
    return flow - rmn;
}
int maxflow, mincost;
inline void run(int s, int t)
{
    MCMF::s = s, MCMF::t = t;
    while (SPFA())
    {
    //    cout<<1<<endl;
        int flow = dfs();
        maxflow += flow;
        mincost += dis[t] * flow;
    }
}
} // namespace MCMF
ll a[100005];
void solve(){
    ll n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        if(a[i]){
            MCMF::addEdge(5001,i,1,0);
        }
        else{
            MCMF::addEdge(i,5002,1,0);
        }
    } 
//    cout<<1<<endl;
    for(int i=1;i<=n;i++){
        if(a[i]==1){
            for(int j=1;j<=n;j++){
                if(a[j]==0){
                    MCMF::addEdge(i,j,1,abs(i-j));
                }
            }
        }
    }
//    cout<<1<<endl;
    MCMF::run(5001,5002);
    cout<<MCMF::mincost<<endl;
}
rush!
原文地址:https://www.cnblogs.com/LH2000/p/14805826.html