Cod sursa(job #40751)

Utilizator unholyfrozenCostea Andrei unholyfrozen Data 27 martie 2007 18:25:55
Problema Pitici Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.85 kb
using namespace std;
#include<stdio.h>
#include<vector>

#define NMAX 1024

void read();
void solve();
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], d[NMAX], cd[NMAX * 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, min;

     d[0] = 0;
     i = 0, j = -1;
     cd[++j] = 0;
     for(; i <= j; i++)
     {
     	z = cd[i];
          for(t = 0; t < N; t++)
          if(C[z][t] && d[t] < d[z] + 1)
          {
          	d[t] = d[z] + 1;
               if(!seen[t])
               cd[++j] = t, seen[t] = 1;
          }
          seen[z] = 0;
     }
     
     for(i = 0; i < N; i++)
     niv[d[i]].push_back(i);
     
	maxn = d[N - 1];
	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 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;
}