Cod sursa(job #286059)

Utilizator CezarMocanCezar Mocan CezarMocan Data 23 martie 2009 13:09:23
Problema Pitici Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.65 kb
#include <cstdio>
#include <vector>
#define maxn 1050

using namespace std;

struct heap {
	int nod, poz;
};

int n, m, k, i, j, p, u, a, b, c, nod, fiu, sz_heap;
vector <int> v[maxn], inv[maxn], csi[maxn];
int cd[maxn], ind[maxn], grad[maxn], ct[maxn];
heap h[3 * maxn];
int cost[maxn][maxn], nrs[maxn], cs[maxn][maxn];


inline int calc_cost(int t) {
	return cost[h[t].nod][h[t].poz] + cs[h[t].nod][fiu];
}

inline void swap(int i, int j) {
	heap aux;
	aux = h[i];
	h[i] = h[j];
	h[j] = aux;
}

void heap_insert(int nod, int poz) {
	int i;
	sz_heap++;
	h[sz_heap].nod = nod;
	h[sz_heap].poz = poz;
	i = sz_heap;
//	fprintf(stderr, "%d %d %d   %d\n", fiu, nod, calc_cost(i), poz);

	while (calc_cost(i) < calc_cost(i / 2) && i > 1) {
		swap(i, i / 2);
		i /= 2;
	}
}

void heap_erase() {
	int i = 1, f1, f2, c;
	swap(1, sz_heap);
	sz_heap--;
	while (2 * i <= sz_heap) {
		f1 = calc_cost(2 * i);
		f2 = calc_cost(2 * i + 1);
		c = calc_cost(i);
		if (2 * i + 1 > sz_heap)
			f2 = 2000000000;
		if (c <= f1 && c <= f2)
			return;

		if (f1 < f2) {
			swap(i, 2 * i);
			i = 2 * i;
		}
		else {
			swap(i, 2 * i + 1);
			i = 2 * i + 1;
		}
		
	}
}


void bf() {
	int ant, i, j;
	p = u = 1;
	cd[1] = 1;
	nrs[1] = 1;

	while (p <= u) {
		nod = cd[p];

		for (i = 0; i < v[nod].size(); i++) {
			fiu = v[nod][i];
			ct[fiu]++;

			if (ct[fiu] == grad[fiu]) {
				//asa merge pe ordinea de la sortarea topologica
				u++;
				cd[u] = fiu;
				memset(h, 0, sizeof(h));
				sz_heap = 0;
				//acuma tre sa calculez jmenu pentru el... adica cele mai bune k
				memset(ind, 0, sizeof(ind));
				for (j = 0; j < inv[fiu].size(); j++) {
					ant = inv[fiu][j];
					nrs[fiu] += nrs[ant];
//					fprintf(stderr, "%d %d\n", fiu, ant);		
					ind[ant] = 1;
					heap_insert(ant, 1); //tre sa fiu atent sa adun si cs[chestie][fiu]
				}
				
//				nrs[fiu] = sz_heap;
				if (nrs[fiu] > k)
					nrs[fiu] = k;

//				fprintf(stderr, "%d %d\n", fiu, nrs[fiu]);

				for (j = 1; j <= k; j++) {
					cost[fiu][j] = cost[h[1].nod][h[1].poz] + cs[fiu][h[1].nod];
					if (h[1].poz < nrs[h[1].nod]) 
						heap_insert(h[1].nod, h[1].poz + 1);
					
					heap_erase(); 
					if (sz_heap == 0)
						break;
				}

/*				fprintf(stderr, "%d\n", fiu);
				for (j = 1; j <= nrs[fiu]; j++)
					fprintf(stderr, "%d ", cost[fiu][j]);
				fprintf(stderr, "\n");*/
			
			}
		}
		p++;
	}
}

int main() {
	freopen("pitici.in", "r", stdin);
	freopen("pitici.out", "w", stdout);

	scanf("%d%d%d", &n, &m, &k);

	for (i = 1; i <= m; i++) {
		scanf("%d%d%d", &a, &b, &c);
		cs[a][b] = cs[b][a] = c;
		grad[b]++;
		v[a].push_back(b);

		inv[b].push_back(a);
	}

	bf();

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


	return 0;
}