Cod sursa(job #176629)

Utilizator plastikDan George Filimon plastik Data 11 aprilie 2008 15:10:32
Problema Cerere Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.47 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];
int Stk[NMAX], lvl;
list<int>::iterator LI[NMAX];

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

	lvl = 0;
	for (Stk[++ lvl] = src; lvl > 0; ) {
		curr = Stk[lvl];
		for (LI[curr] = Neighb[curr].begin(); LI[curr] != Neighb[curr].end(); ++ LI[curr])
			if (Used[*LI[curr]] == false) {
				Used[*LI[curr]] = true;
				Stk[++ lvl] = *LI[curr];
				break;
			}

		if (LI[curr] == Neighb[curr].end()) {
			if (Solver[curr] == 0)
				Ans[curr] = 0;
			else {
				for (need = lvl - Solver[curr], steps = 1; Solver[Stk[need]] != 0; ++ steps)
					need = need - Solver[Stk[need]];
				Ans[curr] = steps;
			}

			-- lvl;
		}
	}

}

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;
}