最小费用最大流

#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <cstring>

using namespace std;

int n, m, src, dst, mc[10010], from[10010], fi[10010], mw[10010], ec;
struct EDGE
{
    int to, weight, cost;
    EDGE() { }
    EDGE(int t, int w, int c) { to = t, weight = w, cost = c; }
} edge[200020];
vector<int> g[10010];

void insert_edge(int s, int d, int w, int c)
{
    edge[ec] = EDGE(d, w, c);
    g[s].push_back(ec++);
    edge[ec] = EDGE(s, 0, -c);
    g[d].push_back(ec++);
}

bool bfs()
{
	for(int i = 1; i <= n; i++) mc[i] = mw[i] = 0x3f3f3f3f;
	mc[src] = 0;
    memset(from, 0, sizeof(from));
    queue<int> q; EDGE e;
    q.push(src);
    do
    {
        int p = q.front();
        q.pop();
        for(int i = 0; i < g[p].size(); i++)
        {
            e = edge[g[p][i]];
            if(e.weight > 0 && mc[e.to] > mc[p] + e.cost)
            {
            	mc[e.to] = mc[p] + e.cost;
            	mw[e.to] = min(mw[p], e.weight);
            	from[e.to] = p;
            	fi[e.to] = i;
                q.push(e.to);
            }
        }
    } while(!q.empty());
    return mc[dst] != 0x3f3f3f3f;
}

int main()
{
    int s, d, w, c;
    scanf("%d%d%d%d", &n, &m, &src, &dst);
    for(int i = 1; i <= m; i++)
    {
        scanf("%d%d%d%d", &s, &d, &w, &c);
        insert_edge(s, d, w, c);
    }
    s = 0, c = 0;
    while(bfs())
    {
	    for(int i = dst; i != src; i = from[i])
		{
			edge[g[from[i]][fi[i]]].weight -= mw[dst];
			edge[g[from[i]][fi[i]] ^ 1].weight += mw[dst];
		}
    	s += mw[dst], c += mw[dst] * mc[dst];
	}
    printf("%d %d\n", s, c);
}
posted @ 2018-02-23 11:26  Js2xxx  阅读(131)  评论(0编辑  收藏  举报