Cod sursa(job #2026084)

Utilizator horiainfoTurcuman Horia horiainfo Data 23 septembrie 2017 17:48:37
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.08 kb
#include <iostream>
#include <queue>
#include <vector>
#include <cstring>

#define N 352
using namespace std;

int nrNodes, m, S, D;
vector<int> Edges[N];
int Capacity[N][N], Cost[N][N];
int Dist[N], Ant[N];

int MinCost[N], RealMinCost[N];

priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > que;

void BellmanFord(int node, int dist){

	if(dist >= Dist[node])	return;

	Dist[node] = dist;
	for(auto next : Edges[node])
		if(Capacity[node][next] != 0)
			BellmanFord(next, dist + Cost[node][next]);
}

bool FindBestPath(){

	memset(MinCost, 0x3f, sizeof(MinCost));
	que.push({0, S});
	MinCost[S] = 0;

	while(!que.empty()){

		int cost = que.top().first,
            node = que.top().second; que.pop();

		if(cost != MinCost[node]) continue;

		for(auto next : Edges[node])
            if(Capacity[node][next]){

                int newCost = MinCost[node] + Cost[node][next] + Dist[node] - Dist[next];
                if(newCost < MinCost[next]){

                    MinCost[next] = newCost;
                    RealMinCost[next] = RealMinCost[node] + Cost[node][next];
                    Ant[next] = node;
                    que.push({newCost, next});
                }
            }
	}

	memcpy(Dist, RealMinCost, sizeof(Dist));
	return MinCost[D] != 0x3f3f3f3f;
}

int main(){

	freopen("fmcm.in", "r", stdin);
	freopen("fmcm.out", "w", stdout);

	scanf("%d%d%d%d", &nrNodes, &m, &S, &D);
	for(; m; m --){

        int x, y;
		scanf("%d%d", &x, &y);
		scanf("%d%d", &Capacity[x][y], &Cost[x][y]);

		Cost[y][x] = -Cost[x][y];
		Edges[x].push_back(y);
		Edges[y].push_back(x);
	}

	memset(Dist, 0x3f, sizeof(Dist));
	BellmanFord(S, 0);

	int minCost = 0;
	while(FindBestPath()){

		int fmin = 0x3f3f3f3f;
		for(int node = D; node != S; node = Ant[node])
			fmin = min(fmin, Capacity[Ant[node]][node]);

		for(int node = D; node != S; node = Ant[node])
			Capacity[Ant[node]][node] -= fmin,
			Capacity[node][Ant[node]] += fmin;

		minCost += fmin * Dist[D];
	}

	printf("%d", minCost);
	return 0;
}