Cod sursa(job #176614)

Utilizator plastikDan George Filimon plastik Data 11 aprilie 2008 14:59:45
Problema Cerere Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.6 kb
// Cerere, Infoarena
// http://infoarena.ro/problema/cerere

#define _CRT_SECURE_NO_DEPRECATE
#include <cstdio>
#include <list>
#include <stack>
using namespace std;

const int NMAX = 100002;

int n;
int Solver[NMAX], Ans[NMAX], Deg[NMAX];
bool Used[NMAX];
list<int> Neighb[NMAX];
list<int> Pred;
list<int>::iterator LI[NMAX];

void depthFirst(int src) {
	int curr, next, steps, need;
	list<int>::reverse_iterator rli;

	for (Pred.push_back(src); Pred.empty() == false; ) {
		curr = Pred.back();
		for (LI[curr] = Neighb[curr].begin(); LI[curr] != Neighb[curr].end(); ++ LI[curr])
			if (Used[*LI[curr]] == false) {
				Used[*LI[curr]] = true;
				Pred.push_back(*LI[curr]);
				break;
			}

		if (LI[curr] == Neighb[curr].end()) {
			if (Solver[curr] == 0)
				Ans[curr] = 0;
			else {
				rli = Pred.rbegin();
				for (need = Solver[curr], steps = 1; rli != Pred.rend(); ++ rli, -- need)
					if (Solver[*rli] == 0 && need == 0)
						Ans[curr] = steps;
					else if (need == 0) {
						need = Solver[*rli];
						++ steps;
					}
			}

			Pred.pop_back();
		}
	}

}

int main() {

	freopen("cerere.in", "r", stdin);
	freopen("cerere.out", "w", stdout);

	scanf("%d", &n);
	int i;
	for (i = 1; i <= n; ++ i)
		scanf("%d", &Solver[i]);
	int v1, v2;
	for (i = 0; i < n; ++ i) {
		scanf("%d %d", &v1, &v2);
		Neighb[v1].push_back(v2);
		-- Deg[v2];
	}

	for (i = 1; i <= n; ++ i)
		if (Deg[i] == 0) {
			Used[i] = true;
			depthFirst(i);
			break;
		}

	for (i = 1; i <= n; ++ i)
		printf("%d ", Ans[i]);

	fclose(stdin);
	fclose(stdout);

	return 0;
}