Cod sursa(job #2026115)

Utilizator horiainfoTurcuman Horia horiainfo Data 23 septembrie 2017 18:44:18
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.3 kb
#include <iostream>
#include <queue>
#include <vector>
#include <cstring>

#define PII pair<int, int>
#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];
bool inQ[N];

int MinCost[N], RealMinCost[N];

priority_queue<PII, vector<PII> , greater<PII> > que;

void BellmanFord(){

	memset(Dist, 0x3f, sizeof(Dist));
	Dist[S] = 0;

	queue<int> que;
	for(que.push(S), inQ[S] = 1; !que.empty(); que.pop()){

		int node = que.front();
		inQ[node] = 0;

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

				if(Dist[node] + Cost[node][next] >= Dist[node])	continue;

				Dist[next] = Dist[node] + Cost[node][next];
				if(inQ[next])	continue;

				inQ[next]	= 1;
				que.push(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);
	}

	BellmanFord();

	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;
}