Cod sursa(job #720217)

Utilizator danalex97Dan H Alexandru danalex97 Data 22 martie 2012 14:18:15
Problema Algola Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.05 kb
#include <cstring>
#include <fstream>
#include <queue>

using namespace std;

const int INF = 1 << 30;

int N, M;
int A[52];
int FlowG[52];
int Cap[52][52];
int Flow[52][1002][52][2];
pair<int, int> Tat[52][1002];
bool Sel[52][1002];
int Tmin, MaxFlow;
queue<pair<int, int> > Q;
pair<int, int> Position;

void Read();
void Build();
void Solve();
bool FindPath(int S);
void Augment(int S);
void Write();

int main()
{
	Read();
	Build();
	Solve();
	Write();
}

void Read()
{
	ifstream fin("algola.in");
	fin >> N >> M;
	for (int i = 1; i <= N; ++i)
		fin >> A[i];
	for (int i = 1, nod1, nod2, cap; i <= M; ++i)
	{
		fin >> nod1 >> nod2 >> cap;
		Cap[nod1][nod2] = Cap[nod2][nod1] = cap;
	}
	fin.close();
}

void Build()
{
	for (int i = 1; i <= N; ++i)
		Cap[i][i] = INF;
}

void Solve()
{
	for (int i = 2; i <= N; ++i)
		while (FlowG[i] < A[i])
		{
			while (FindPath(i) && FlowG[i] < A[i])
				Augment(i);
			if (FlowG[i] < A[i])
				++Tmin;
		}

}

bool FindPath(int S)
{
	while (!Q.empty()) Q.pop();
	memset(Sel, 0, sizeof(Sel));

	Q.push(make_pair(S, 0));
	Sel[S][0] = true;

	while (!Q.empty())
	{
		pair<int, int> now = Q.front(); Q.pop();
		for (int i = 1; i <= N; ++i)
		{
			if (!Cap[now.first][i]) continue;

			if (now.second + 1 <= Tmin && !Sel[i][now.second + 1] && Flow[now.first][now.second][i][0] < Cap[now.first][i])
			{
				Tat[i][now.second + 1] = make_pair(now.first, 0);
				if (i == 1)
				{
					Position = make_pair(i, now.second + 1);
					return true;
				}
				Sel[i][now.second + 1] = true;
				Q.push(make_pair(i, now.second + 1));
			}
			if (now.second - 1 >= 0 && !Sel[i][now.second - 1] && Flow[now.first][now.second][i][1] < 0)
			{
				Tat[i][now.second - 1] = make_pair(now.first, 1);
				if (i == 1)
				{
					Position = make_pair(i, now.second - 1);
					return true;
				}
				Sel[i][now.second - 1] = true;
				Q.push(make_pair(i, now.second - 1));
			}
		}
	}
	return false;
}

void Augment(int S)
{
	pair<int, int> i, j;
	i = Position;
	j = make_pair(Tat[i.first][i.second].first, i.second + (Tat[i.first][i.second].second == 0 ? -1 : 1));

	int MaxCapacity = INF, Limit = A[S] - FlowG[S];

	while (i.second != 0)
	{
		MaxCapacity = min(MaxCapacity, Cap[j.first][i.first] - Flow[j.first][j.second][i.first][Tat[i.first][i.second].second]);
		i = j;
		j = make_pair(Tat[i.first][i.second].first, i.second + (Tat[i.first][i.second].second == 0 ? -1 : 1));
	}

	MaxCapacity = min(MaxCapacity, Limit);

	i = Position;
	j = make_pair(Tat[i.first][i.second].first, i.second + (Tat[i.first][i.second].second == 0 ? -1 : 1));
	while (i.second != 0)
	{
		Flow[j.first][j.second][i.first][Tat[i.first][i.second].second] += MaxCapacity;
		Flow[i.first][i.second][j.first][!Tat[i.first][i.second].second] -= MaxCapacity;
		i = j;
		j = make_pair(Tat[i.first][i.second].first, i.second + (Tat[i.first][i.second].second == 0 ? -1 : 1));
	}

	FlowG[S] += MaxCapacity;
}

void Write()
{
	ofstream fout("algola.out");
	fout << Tmin;
	fout.close();
}