Luogu P4015 运输问题

Posted maomao9173

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu P4015 运输问题相关的知识,希望对你有一定的参考价值。

题目链接 (Click) (Here)

继续颓网络流(hhhhh),虽然这次写的是个大水题,但是早上水一个网络流果然还是让人心情舒畅啊~

最大费用最大流不用非得反着费用建边.只要没有正环,初始化的时候小心一点就好啦~

#include <bits/stdc++.h>
using namespace std;

const int INF = 0x3f3f3f3f;

int cnt = -1, head[210];

struct edge {
    int nxt, to, w, f;
}e[40010];

void add_edge (int from, int to, int flw, int val) {
    e[++cnt].nxt = head[from];
    e[cnt].to = to;
    e[cnt].f = flw;
    e[cnt].w = val;
    head[from] = cnt;
}

void add_len (int u, int v, int f, int w) {
    add_edge (u, v, f, +w);
    add_edge (v, u, 0, -w);
}

int _head[210]; edge _e[40010];
int n, m, numA[110], numB[110], cost[110][110];

int A (int x) {return n * 0 + x;}
int B (int x) {return n * 1 + x;}

queue <int> q;
int dis[210], vis[210], flow[210];
int pre_edge[210], pre_node[210];

bool can_use (int u, int v, int i, int type) {
    if (type == +1) return dis[v] > dis[u] + e[i].w;
    if (type == -1) return dis[v] < dis[u] + e[i].w;
}

int spfa (int s, int t, int type) {
    memset (vis, 0, sizeof (vis));
    memset (flow, 0x3f, sizeof (flow));
    if (type == +1) memset (dis, +0x3f, sizeof (dis));
    if (type == -1) memset (dis, -0x3f, sizeof (dis));
    vis[s] = true; dis[s] = 0; q.push (s);
    while (!q.empty ()) {
        int u = q.front (); q.pop ();
        for (int i = head[u]; ~i; i = e[i].nxt) {
            int v = e[i].to;
            if (can_use (u, v, i, type) && e[i].f) {
                dis[v] = dis[u] + e[i].w;
                flow[v] = min (flow[u], e[i].f);
                pre_edge[v] = i;
                pre_node[v] = u;
                if (!vis[v]) {
                    vis[v] = true;
                    q.push (v);
                }
            }
        }
        vis[u] = false;
    }
    return flow[t] != INF;
}

int MCMF (int s, int t, int type) {
    int cost = 0;
    while (spfa (s, t, type)) {
        cost += dis[t] * flow[t];
        int u = t;
        while (u != s) {
            e[pre_edge[u] ^ 0].f -= flow[t];
            e[pre_edge[u] ^ 1].f += flow[t];
            u = pre_node[u];
        } 
    }
    return cost;
}

int main () {
    memset (head, -1, sizeof (head));
    cin >> n >> m;
    int s = n + m + 1;
    int t = n + m + 2;
    for (int i = 1; i <= n; ++i) {cin >> numA[i]; add_len (s, A (i), numA[i], 0);}
    for (int i = 1; i <= m; ++i) {cin >> numB[i]; add_len (B (i), t, numB[i], 0);}
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            cin >> cost[i][j];
            add_len (A (i), B (j), INF, cost[i][j]);
        }
    }
    memcpy (_e, e, sizeof (e)); memcpy (_head, head, sizeof (head));
    cout << MCMF (s, t, +1) << endl;
    memcpy (e, _e, sizeof (e)); memcpy (head, _head, sizeof (head));
    cout << MCMF (s, t, -1) << endl;
}

以上是关于Luogu P4015 运输问题的主要内容,如果未能解决你的问题,请参考以下文章

P4015 运输问题 最大/最小费用最大流

洛谷 P4015 运输问题 最小费用最大流+最大费用最大流

luogu p4015(最小费用最大流)

[网络流24题]运输问题

[Luogu] 运输问题 -- 00

[Luogu] 货车运输