Cod sursa(job #40704)

Utilizator unholyfrozenCostea Andrei unholyfrozen Data 27 martie 2007 17:41:59
Problema Pitici Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.73 kb
using namespace std;
#include<stdio.h>
#include<vector>

#define NMAX 1024

void read();
void solve();
void dfs(int x, int y);
void sift(int x, int y);
void percolate(int x, int y);

int C[NMAX][NMAX], N, M, K, A[NMAX][NMAX], nrv[NMAX], maxn, B[NMAX], lim, wh[NMAX], poz[NMAX], seen[NMAX], pe[NMAX];
vector<int> niv[NMAX];

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

     read();
     solve();
	return 0;
}

void read()
{
	int a, b, c;
     
	scanf("%d%d%d", &N, &M, &K);
     for(;M--;)
     {
     	scanf("%d%d%d", &a, &b, &c);
          C[a - 1][b - 1] = c;
     }
}

void solve()
{
	int i, j, z, t;
     
	dfs(0, 0);
     for(i = 0; i < N; i++)
     niv[pe[i]].push_back(i);
     
	A[0][0] = 0, nrv[0] = 1;
	for(i = 1; i <= maxn; i++)
	{
     	for(z = 0; z < niv[i].size(); z++)
          {
               j = niv[i][z];
               lim = 0;
               for(t = 0; t < N; t++)
               if(C[t][j])
               {
               	poz[t] = 0;
				B[++lim] = t;
                    wh[t] = lim;
                    percolate(lim, j);
               }
               for(; nrv[j] < K;)
               {
               	if(lim == 0) break;
                    
                    t = B[1];
                    A[j][nrv[j]++] = A[t][poz[t]++] + C[t][j];
                    if(poz[t] < nrv[t])
                    sift(1, j);
                    else
                    {
                    	B[1] = B[lim];
                         wh[B[1]] = 1;
                         lim--;
                         sift(1, j);
                    }
               }
          }
     }
     for(i = 0; i < K; i++)
     printf("%d ", A[N - 1][i]);
     printf("\n");
}

void dfs(int x, int y)
{
	int i;
     if(pe[x] < y) pe[x] = y;
     if(seen[x]) return;
     seen[x] = 1;
     
     if(y > maxn) maxn = y;
     
     for(i = 0; i < N; i++)
     if(C[x][i])
    	dfs(i, y + 1);
}

void sift(int x, int y)
{
	int son, aux;

     son = x;
     if(2 * x <= lim)
     {
     	son = 2 * x;
          if(son + 1 <= lim && A[B[son + 1]][poz[B[son + 1]]] + C[B[son + 1]][y] < A[B[son]][poz[B[son]]] + C[B[son]][y])
		son++;
     }
     while(A[B[x]][poz[B[x]]] + C[B[x]][y] > A[B[son]][poz[B[son]]] + C[B[son]][y])
     {
		aux = B[x], B[x] = B[son], B[son] = aux;
          wh[B[x]] = x, wh[B[son]] = son;
          x = son;
          if(2 * x <= lim)
	     {
	     	son = 2 * x;
	          if(son + 1 <= lim && A[B[son + 1]][poz[B[son + 1]]] + C[B[son + 1]][y] < A[B[son]][poz[B[son]]] + C[B[son]][y])
			son++;
	     }
     }
}

void percolate(int x, int y)
{
	int aux = B[x];

     for(;x >= 2 && A[B[x >> 1]][poz[B[x >> 1]]] + C[B[x >> 1]][y] > A[aux][poz[aux]] + C[aux][y]; x >>= 1)
	B[x] = B[x >> 1], wh[B[x]] = x;

     B[x] = aux, wh[B[x]] = x;
}