Cod sursa(job #1999290)

Utilizator theodor.moroianuTheodor Moroianu theodor.moroianu Data 10 iulie 2017 20:12:53
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.26 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

struct Edge
{
	int from, to, flow, cost;
	Edge(int _from, int _to, int _flow, int _cost) : from(_from), to(_to), flow(_flow), cost(_cost) { }
};

struct Graph
{
	vector <vector <int>> adia;
	vector <Edge> edges;
	vector <int> potential, dist, father;
	int n, d, s;

	Graph(int _n, int _s, int _d) : n(_n), s(_s), d(_d), adia(vector <vector <int>>(_n + 1)) { }

	void add_edge(Edge x) {
		adia[x.from].push_back(edges.size()), edges.push_back(x);
		adia[x.to].push_back(edges.size()), edges.push_back({ x.to, x.from, 0, -x.cost });
	}

	void bellman()
	{
		dist = vector <int>(n + 1, 1e9);
		queue <int> q({ s });
		vector <int> inqueue(n);
		inqueue[s] = 1;
		dist[s] = 0;

		while (!q.empty()) {
			int x = q.front();
			inqueue[x] = 0;
			q.pop();

			for (auto i : adia[x]) {
				if (edges[i].flow && dist[edges[i].to] > dist[x] + edges[i].flow) {
					dist[edges[i].to] = dist[x] + edges[i].cost;
					if (!inqueue[edges[i].to])
						q.push(edges[i].to), inqueue[edges[i].to] = 1;
				}
			}
		}
	}

	bool djk()
	{
		potential = dist;
		dist = vector <int>(n + 1, 1e9);
		father = vector <int>(n + 1, 1e9);
		dist[s] = 0;
		priority_queue <pair <int, int>> q;
		q.push({ 0, s });

		while (!q.empty()) {
			int x(q.top().second), t(-q.top().first);
			q.pop();

			if (dist[x] != t)
				continue;

			for (auto i : adia[x]) {
				int cost(-potential[edges[i].to] + potential[x] + edges[i].cost);
				if (edges[i].flow && dist[edges[i].to] > dist[x] + cost) {
					dist[edges[i].to] = dist[x] + cost;
					father[edges[i].to] = i;
					q.push({ -dist[edges[i].to], edges[i].to });
				}
			}
		}

		for (int i(1); i <= n; i++)
			dist[i] += potential[i];

		return father[d] != 1e9;
	}

	pair <int, int> mincostmaxflow()
	{
		bellman();
		int cost(0), flow(0);

		while (djk()) {
			int mxm(1e9);
			for (int i(d); i != s; i = edges[father[i]].from)
				mxm = min(mxm, edges[father[i]].flow);
			flow += mxm;
			for (int i(d); i != s; i = edges[father[i]].from) {
				edges[father[i]].flow -= mxm;
				edges[father[i] ^ 1].flow += mxm;
				cost += edges[father[i]].cost * mxm;
			}
		}
		return { flow, cost };
	}
};

Graph x(0, 0, 0);

int main()
{
	/*ios_base::sync_with_stdio(0);
	cin.tie(0);


	int n;
	cin >> n;

	vector <int> v(n);

	for (int i(0); i < n; i++)
		cin >> v[i];

	Graph x(2 * n + 4, 2 * n + 1, 2 * n + 3);

	for (int i(1); i <= n; i++)
		x.add_edge({ i, n + i, 1, -1 });

	for (int i(1); i < n; i++)
		for (int j(i + 1); j <= n; j++)
			if (v[i - 1] == 1 + v[j - 1] || v[i - 1] == -1 + v[j - 1] || v[i - 1] % 7 == v[j - 1] % 7 || v[i - 1] == v[j - 1])
				x.add_edge({ n + i, j, 1, 0 });

	for (int i(1); i <= n; i++)
		x.add_edge({ 2 * n + 1, i, 1, 0 }), x.add_edge({ n + i, 2 * n + 2, 1, 0 });

	x.add_edge({ 2 * n + 2, 2 * n + 3, 4, 0 });

	cout << -x.mincostmaxflow().second;
	/*/int n, m, s, d;
	ifstream in("fmcm.in");
	ofstream out("fmcm.out");

	in >> n >> m >> s >> d;

	x = Graph(n + 1, s, d);

	int a, b, c;
	while (m--) {
		in >> a >> b >> c >> d;
		x.add_edge({ a, b, c, d });
	}

	out << x.mincostmaxflow().second;
	//*/
	return 0;
}