Cod sursa(job #284236)

Utilizator savimSerban Andrei Stan savim Data 21 martie 2009 12:31:02
Problema Pitici Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.83 kb
#include <stdio.h>
#include <vector>
#include <string.h>

using namespace std;

#define MAX_N 1024
#define inf 2147000000

int n, m, k, q;
struct legaturi {
	int x;
	int y;
	int c;
} muchie[MAX_N];
vector <int> A[MAX_N], C[MAX_N];
int nr[MAX_N], v[MAX_N], ind[MAX_N], loc[MAX_N];
int drum[MAX_N][MAX_N], heap[4 * MAX_N], vheap[MAX_N];

void topol_sort() {
	for (int i = 1; i <= m; i++)
		nr[muchie[i].y]++;
	
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++)
			if (nr[j] == 0) {
				v[i] = j;
				
				nr[j]--;
				
				int len = A[j].size();
				for (int k = 0; k < len; k++)
					nr[A[j][k]]--;
				
				break;
			}
	}
}

void cit() {
	freopen("pitici.in", "r", stdin);
	freopen("pitici.out", "w", stdout);

	scanf("%d %d %d", &n, &m, &k);
	for (int i = 1; i <= m; i++) {
		scanf("%d %d %d", &muchie[i].x, &muchie[i].y, &muchie[i].c);
		A[muchie[i].x].push_back(muchie[i].y);
		C[muchie[i].x].push_back(muchie[i].c);
	}
	
	topol_sort();
}

void push_back_heap(int val, int vine) {
	heap[++q] = val; vheap[q] = vine;
	
	int poz = q;
	while (heap[poz] < heap[poz / 2]) {
		int aux = heap[poz / 2];
		heap[poz / 2] = heap[poz];
		heap[poz] = aux;
		
		aux = vheap[poz / 2];
		vheap[poz / 2] = vheap[poz];
		vheap[poz] = aux;
		
		poz /= 2;
	}
}

void heap_pop() {
	int aux = 0, poz = 1;
	aux = heap[1]; heap[1] = heap[q]; heap[q] = aux;
	aux = vheap[1]; vheap[1] = vheap[q]; vheap[q] = aux;
	
	heap[q] = vheap[q] = 0;
	q--;
	
	while ((heap[poz * 2] < heap[poz] && heap[poz * 2]) || (heap[poz * 2 + 1] < heap[poz] && heap[poz * 2 + 1])) {
		int nxt = poz * 2;
		if (heap[nxt] == 0) nxt = poz * 2 + 1;
		else {
			if (heap[poz * 2 + 1] && heap[poz * 2 + 1] < heap[poz * 2])
				nxt = poz * 2 + 1;
		}
		
		aux = heap[poz]; heap[poz] = heap[nxt]; heap[nxt] = aux;
		aux = vheap[poz]; vheap[poz] = vheap[nxt]; vheap[nxt] = aux;
	}
	
}

void solve() {
	drum[n + 1][0] = 1; 
	A[n].push_back(n + 1);
	C[n].push_back(0);

	for (int i = n; i >= 1; i--) {
		//iau din fiecare cabana inferioara 

		memset(heap, 0, sizeof(heap));
		memset(vheap, 0, sizeof(vheap));
		memset(ind, 0, sizeof(ind));
		memset(loc, 0, sizeof(loc));
		q = 0;
		
		int len = A[v[i]].size();
		for (int j = 0; j < len; j++) {
			loc[A[v[i]][j]] = j;
			push_back_heap(drum[A[v[i]][j]][1] + C[v[i]][j], A[v[i]][j]);
			ind[A[v[i]][j]] = 1;
		}

		int j = 0;
		while (vheap[1] && j < k) {
			int vine = vheap[1];
			
			drum[i][++j] = heap[1];
			
			heap_pop();
			
			if (ind[vine] < drum[vine][0]) {
				ind[vine]++;
				push_back_heap(drum[vine][ind[vine]] + C[v[i]][loc[vine]], vine);
			}
		}
		drum[v[i]][0] = j;
	}
}

void write() {
	for (int i = 1; i <= k; i++)
		printf("%d ", drum[1][i]);
	printf("\n");
}

int main() {

	cit();
	solve();
	write();
	
	return 0;
}