Cod sursa(job #424254)

Utilizator radu_voroneanuVoroneanu Radu Stefan radu_voroneanu Data 24 martie 2010 18:27:54
Problema Pitici Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.12 kb
#include <stdio.h>
#include <algorithm>
#include <vector>
#define MAXN 1024
#define MAXK 1024
#define INF 1000000000

using namespace std;

int sol[MAXN][MAXK];
pair<int, int> H[MAXN];
vector< pair<int, int> > a[MAXN], b[MAXN];
int L[MAXN], W[MAXN];
int coada[MAXN];
int grad[MAXN];
int i,n,m,k,x,y,cost,nod,nr,j,st,dr;

inline int f(pair<int, int> x)
{ return sol[x.first][W[x.first]] + x.second; }

void heapup(int nod)
{
	int x, tata;
	while (nod>1){
		x = f(H[nod]);
		tata = f(H[nod/2]);
		if (x<tata){
			swap(H[nod],H[nod/2]);
			nod/=2;
		}
		else break;
	}
}

void heapdown(int nod)
{
	int fi1, fi2, x1,x2,el, fiu, xfiu;
	while (nod <=nr){
		fi1 = nod<<1; fi2 = fi1+1;
		x1 = (fi1<=nr)?f(H[fi1]):INF;
		x2 = (fi2<=nr)?f(H[fi2]):INF;
		if (x1<x2){ fiu=fi1; xfiu=x1; }
		else { fiu=fi2; xfiu=x2;}
		el = f(H[nod]);
		if (el>xfiu){
			swap(H[fiu],H[nod]);
			nod=fiu;
		}
		else break;
	}
}

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

	//citire
	scanf("%d %d %d",&n,&m,&k);
	for (i=1; i<=m; i++){
		scanf("%d %d %d",&x,&y,&cost);
		a[y].push_back(make_pair(x,cost));
		b[x].push_back(make_pair(y,cost));
		grad[y] ++;
	}

	//sortare topologica
	coada[1] = 1;
	vector<pair<int, int> >::iterator it;
	for (st=dr=1; st<=dr; st++){
		nod = coada[st];
		for (it=b[nod].begin(); it!=b[nod].end(); ++it){
			int nod2= it->first;
			grad[nod2]--;
			if (grad[nod2]==0)
				coada[++dr] = nod2;
		}
	}

	//solution
	memset(L,0,sizeof(L));
	memset(sol,1,sizeof(sol));
	sol[1][1] = 0;
	L[1] = 1;
	for (i=2; i<=dr; i++){
		for (j=1; j<=n; j++)
			W[j] = 1;
		nod = coada[i];
		nr = 0;
		for (it=a[nod].begin(); it!=a[nod].end(); ++it){
			H[++nr].first = it->first;
			H[nr].second = it->second;
			heapup(nr);
		}
		for (; nr && L[nod]<k;){
			L[nod]++;
			sol[nod][L[nod]] = f(H[1]);
			W[H[1].first]++;
			if (W[H[1].first] <= L[H[1].first]) heapdown(1);
			else {
				swap(H[1],H[nr]);
				nr--;
				heapdown(1);
			}
		}
	}

	//afisare
	for (i=1; i<k; i++)
		printf("%d ",sol[n][i]);
	printf("%d\n",sol[n][k]);
	return 0;
}