P3381 [template] Minimum Cost Maximum (MCMF)

P3381 [template] Minimum Cost Maximum

If that subject description, given a network diagram, and the source and sink, each side units is known maximum flow and traffic charges, which determine the maximum flow and minimum cost network in the case of maximum flow.

Input format The first line contains four positive integers N, M, S, T, respectively, the number of points, with a number of the edges, the source-point number, serial number sink.

Next M lines contains four integer ui, vi, wi, fi, denotes the i th ui from there to the edge and arriving at VI, the right side of wi (i.e., the side of the maximum flow rate Wi), per unit flow rate fee fi.

Format output one line containing two integers, followed by the maximum flow and minimum cost at maximum flow conditions.

Sample input and output

输入 #1 复制

4 5 4 3
4 2 30 2
4 3 20 3
2 3 20 1
2 1 30 9
1 3 40 5
输出 #1 复制

50 280

Description / Tip constraints of time: 1000ms, 128M

(BYX: The last two points into the 1200ms)

Data Scale:

For 30% of the data: N <= 10, M <= 10

For 70% of the data: N <= 1000, M <= 1000

To 100% of the data: N <= 5000, M <= 50000

Sample Description:

Here Insert Picture Description

As shown, the optimal solutions are as follows:

The first stream is a 4-> 3, flow rate of 20, a cost of 3 * 20 = 60.

The second stream is 4-> 2-> 3, flow rate of 20, the cost is (2 + 1) * 20 = 60.

Third stream is 4-> 2-> 1-> 3, flow rate of 10, costs (9 + 2 + 5) * 10 = 160.

Therefore, the maximum flow rate is 50, the minimum cost in this case is 60 + 60 + 160 = 280.

Therefore, the output of 50,280.

Thinking

Spfa + Dinic

Solution to a problem as follows

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

#define INF 0x3f3f3f3f
#define ll long long
const int maxn = 5005;
const int maxm = 150000;
int n, m, s, e;
struct Edge
{
    int v, w, cap, next;
} edge[maxm];
int head[maxn], dis[maxn], use[maxn];
int pre[maxn], last[maxm];      //pre 是用来存储上一个节点的, 而last 则是存储上一个边
int flow[maxn];
int k = -1;
ll mx_flw = 0, mn_cst = 0;

void Add(int u, int v, int w, int cap)
{
    edge[++ k] = (Edge){ v, w, cap, head[u]}; head[u] = k;
    edge[++ k] = (Edge){ u, -w, 0, head[v]};  head[v] = k;
}

bool Spfa(int s, int e)
{
    int ar[10];
    for(int i = 0; i <= n; i ++)
        dis[i] = INF, use[i] = 0, flow[i] = INF;
    dis[s] = 0;
    queue<int> q;
    q.push(s);
    int u,v,w;
    while(! q.empty())
    {
        u = q.front(); q.pop();
        use[u] = 0;

        for(int i = head[u]; i != -1; i = edge[i].next)
        {
            v = edge[i].v;
            w = edge[i].w;
            if(edge[i].cap && dis[v] > dis[u] + w)
            {
                dis[v] = dis[u] + w;
                pre[v] = u;
                last[v] = i;
                flow[v] = min(flow[u], edge[i].cap);
                if(! use[v])
                {
                    q.push(v);
                    use[v] = 1;
                }
            }
        }
    }
    if(flow[e] != INF)
        return true;
    return false;
}

void MCMF(int s, int e)
{
    while(Spfa(s, e))
    {
        mx_flw += flow[e];
        mn_cst += flow[e]*1LL * dis[e]*1LL;
        int now = e;
        while(now != s)     //更新 残量
        {
            edge[last[now]].cap -= flow[e];
            edge[last[now]^1].cap += flow[e];
            now = pre[now];
        }
    }
}

void init()
{
    k = -1;
    for(int i = 0; i <= n; i ++)
        head[i] = -1;
    mx_flw = 0, mn_cst = 0;
}

int main()
{
    ios::sync_with_stdio(false); cin.tie(0);
    //freopen("T.txt","r",stdin);
    while(cin >> n >> m >> s >> e)
    {
        init();
        int u, v, cap, w;
        for(int i = 1; i <= m; i ++)
            cin >> u >> v >> cap >> w, Add(u, v, w, cap);
        MCMF(s, e);
        cout << mx_flw << " " << mn_cst << endl;
    }

    return 0;
}
Published 122 original articles · won praise 191 · views 20000 +

Guess you like

Origin blog.csdn.net/qq_34261446/article/details/104563650