Cod sursa(job #1801257)

Utilizator theodor.moroianuTheodor Moroianu theodor.moroianu Data 8 noiembrie 2016 20:05:20
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.84 kb
#include <fstream>
#include <queue>
#include <algorithm>
using namespace std;

int tata[400];
int adia[300][300], cost[300][300];
int val[300];
int S = 1, D, NMAX;
struct a
{
	int cost, tata, nod;
	a() { }
	a(int _cost, int _nod, int _tata) : nod(_nod), cost(_cost), tata(_tata) { }
	bool operator< (const a & q) const
	{
		return (cost > q.cost);
	}
};


bool djk(); /// 0 if no path found
int find();
void update(int q);
void solve_flux();

int main()
{
	ifstream in("cc.in");
	int m;
	in >> m;
	S = 1, D = NMAX = 2 * m + 2;

	for (int i = 2; i <= m + 1; i++)
		adia[1][i] = adia[i + m][2 * m + 2] = 1;

	for (int i = 2; i < m + 2; i++) {
		for (int j = m + 2; j < 2 * m + 2; j++) {
			in >> cost[i][j];
			cost[j][i] = -cost[i][j];
			adia[i][j] = 1;
		}
	}

	solve_flux();

	ofstream out("cc.out");
	int r = 0;

	for (int i = 2; i < m + 2; i++)
		for (int j = m + 2; j < 2 * m + 2; j++)
			if (adia[i][j] == 0)
				r += cost[i][j];

	out << r;

	return 0;
}

void update(int q)
{
	for (int i = D; tata[i] != -1; i = tata[i]) {
		adia[tata[i]][i] -= q;
		adia[i][tata[i]] += q;
	}
}

int find()
{
	int minim = 1e9;
	for (int i = D; tata[i] != -1; i = tata[i]) {
		minim = min(minim, adia[tata[i]][i]);
	}
	return minim;
}

bool djk()
{
	priority_queue <a> q;
	for (int i = 1; i <= NMAX; i++)
		val[i] = 1e9;

	q.push({ 0, S, -1 });
	val[S] = 0;

	while (!q.empty()) {
		int nod = q.top().nod, c = q.top().cost, t = q.top().tata;
		q.pop();
		if (c > val[nod])
			continue;

		tata[nod] = t;

		if (nod == D)
			return true;

		for (int i = 0; i <= NMAX; i++) {
			if (adia[nod][i] > 0 && c + cost[nod][i] < val[i]) {
				val[i] = c + cost[nod][i];
				q.push({ val[i], i, nod });
			}
		}
	}
	return false;
}

void solve_flux()
{
	while (djk()) {
		update(1 /*find()*/);
	}
}