Cod sursa(job #2085294)

Utilizator silviu982001Borsan Silviu silviu982001 Data 9 decembrie 2017 21:48:05
Problema Flux maxim de cost minim Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.41 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstdio>
#include <unordered_set>
#include <cstring>

#define INF 0x0f0f0f0f

using namespace std;

int n,m,s,d, capacitate[350][350], cost[350][350], dist[350], parent[350], fmcm;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> heap;
vector<unordered_set<int>> v;

void bf()
{
	unordered_set<int> inq;
	queue<int> q;
	q.push(s);
	inq.insert(s);
	memset(dist, INF, sizeof(dist)); 
	dist[s] = 0;

	while(!q.empty())
	{
		int nod = q.front();
		q.pop();
		inq.erase(nod);
		for(unordered_set<int>::const_iterator it = v[nod].begin(); it != v[nod].end(); ++it)
			if (capacitate[nod][*it] != 0)
			{
				int d = dist[nod] + cost[nod][*it];
				if (d < dist[*it])
				{
					dist[*it] = d;
					if (inq.find(*it) == inq.end())
					{
						inq.insert(*it);
						q.push(*it);
					}
				}
			}
	}
}

int main()
{
	fmcm = 0;
	ifstream input("fmcm.in");
	input >> n >> m >> s >> d;
	--s;
	--d;
	v = vector<unordered_set<int>>(n);
	int x,y,c,z;
	for (int i = 0;i<m;i++)
	{
		input >> x >> y >> c >> z;
		--x;
		--y;
		capacitate[x][y] = c;
		cost[x][y] = z;
		cost[y][x] = -z;
		v[x].insert(y);
		v[y].insert(x);
	}
	input.close();
	bf();
	int partial[350], real[350];
	for(;;)
	{
		memset(partial, INF, sizeof(partial));
		partial[s] = 0;
		real[s] = 0;
		heap.push(make_pair(partial[s], s));

		while (!heap.empty())
		{
			int curMin = heap.top().first;
			int curNod = heap.top().second;
			heap.pop();

			for(unordered_set<int>::const_iterator it = v[curNod].begin(); it != v[curNod].end(); ++it)
				if (capacitate[curNod][*it] != 0)
				{
					int minDist = partial[curNod] + cost[curNod][*it] + dist[curNod] - dist[*it];
					if (partial[*it] > minDist)
					{
						partial[*it] = minDist;
						parent[*it] = curNod;
						real[*it] = real[curNod] + cost[curNod][*it];
						heap.push(make_pair(partial[*it], curNod));
					}
				}
		}

		if (partial[d] == INF)
			break;

		memcpy(dist, real, sizeof(real));

		int minim = INF;

		for(int u = d; u != s; u = parent[u])
			minim = min(minim, capacitate[parent[u]][u]);

		for(int u = d; u != s; u = parent[u])
		{
			capacitate[parent[u]][u] -= minim;
			capacitate[u][parent[u]] += minim;
		}

		fmcm += real[d] * minim;
	}

	ofstream output("fmcm.out");
	output << fmcm;
	output.close();
	return 0;
}