Cod sursa(job #40773)

Utilizator unholyfrozenCostea Andrei unholyfrozen Data 27 martie 2007 18:43:12
Problema Pitici Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.48 kb
#include<stdio.h>

#define NMAX 1024

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

int C[NMAX][NMAX], N, M, K, A[NMAX][NMAX], nrv[NMAX], B[NMAX], lim, wh[NMAX], poz[NMAX], seen[NMAX], list[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, min;

     lim = N - 1;
     df(0);
     
	A[0][0] = 0, nrv[0] = 1;
	for(i = 1; i < N; i++)
	{
               j = list[i];
               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 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;
}

void df(int x)
{
	int i;

     seen[x] = 1;
     for(i = 0; i < N; i++)
     if(!seen[i] && C[x][i])
     df(i);
     list[lim--] = x;
}