Cod sursa(job #171648)

Utilizator marius.pungaruMarius Pungaru marius.pungaru Data 4 aprilie 2008 18:59:34
Problema Salvare Scor 50
Compilator c Status done
Runda Arhiva de probleme Marime 2.25 kb
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define FIN "salvare.in"
#define FOUT "salvare.out"
#define MAX_N 1024

int N, M, L, *T[MAX_N], C[MAX_N], E[MAX_N], U[MAX_N], S[MAX_N], I[MAX_N], P[MAX_N], X[MAX_N], Y[MAX_N];

void enumerate(int Q[])
{
     int ql = 0, qr = -1, i;
     
     for (i = 1, L = 0; i <= N; i++)
         if (C[i] == 1)
            C[Q[++qr] = i] = 0, L++;
     for (; ql <= qr; ql++)
     {
         int *p = T[Q[ql]];
         for (; *p && (!C[*p]); p++) ;
         C[*p]--;
         P[Q[ql]] = *p;
         if (C[*p] == 1)
            C[Q[++qr] = *p] = 0;
     }
}

inline int max(int a, int b)
{
       return a > b ? a : b;
}

inline int min(int a, int b)
{
       return a < b ? a : b;
}

int resolve(int len)
{
    int i, cnt = 0;

    memset(U, 0, sizeof(U));
    memset(S, 0xf3, sizeof(S));
    memset(I, 0x3f, sizeof(I));
    
    for (i = 0; i < L; i++)
        S[E[i]] = I[E[i]] = 1;
    for (i = 0; i < N; i++)
    {
        int e = E[i], p = P[e];

        if (S[e] > len)
           U[E[i]] = 1, I[e] = S[e] = -len, cnt++;
        else
        if (I[e] < 0 && S[e] > 0 && S[e] - 1 <= -I[e])
           S[e] = I[e];
              
        S[p] = max(S[e] + 1, S[p]);
        I[p] = min(I[e] + 1, I[p]);
    } 
    if (S[E[N - 1]] > 0)
       U[E[N - 1]] = 1, cnt++;

    return cnt;
}

int main(void)
{
    int i, bit, len, cnt = 0;
    
    freopen(FIN, "r", stdin);
    freopen(FOUT, "w", stdout);
    
    scanf("%d%d", &N, &M);
    for (i = 1; i < N; i++)
    {
        scanf("%d%d", X + i, Y + i);
        C[X[i]]++, C[Y[i]]++;
    }
    for (i = 1; i <= N; i++)
        T[i] = (int *) malloc(sizeof(int) * (C[i] + 1));
    memset(C, 0, sizeof(C));
    for (i = 1; i < N; i++)
    {
        T[X[i]][C[X[i]]++] = Y[i];
        T[Y[i]][C[Y[i]]++] = X[i];
    }
    for (i = 1; i <= N; i++)
        T[i][C[i]] = 0;
        
    enumerate(E);

    for (bit = 1; bit <= N; bit <<= 1) ;
    for (len = N; bit; bit >>= 1)
        if (len - bit >= 0 && resolve(len - bit) <= M)
           len -= bit;
           
    resolve(len);
    printf("%d\n", len);
    for (i = 1; i <= N; i++)
        if (U[i])
           printf("%d ", i);  
  
    return 0;
}