Cod sursa(job #170678)

Utilizator marius.pungaruMarius Pungaru marius.pungaru Data 3 aprilie 2008 00:38:44
Problema Salvare Scor 20
Compilator c Status done
Runda Arhiva de probleme Marime 3.74 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TESTING
#define DEBUG

#undef DEBUG

#ifndef TESTING
    #define FIN "cabane.in"
    #define FOUT "cabane.out"
#else
    #define FIN "salvare.in"
    #define FOUT "salvare.out"
#endif

#define MAX_N 100002

int *T[MAX_N], deg[MAX_N], parent[MAX_N], aux_deg[MAX_N], Q[MAX_N], U[MAX_N], request[MAX_N], extra[MAX_N], *X, *Y, N, M;

void enumerate(int Q[])
{
     int ql = 0, qr = -1, i;
     
     memcpy(aux_deg, deg, sizeof(deg));
     for (i = 1; i <= N; i++)
         if (aux_deg[i] == 1)
            Q[++qr] = i;
            
     for (; ql <= qr; ql++)
     {
         int expand_node = Q[ql];
         
         for (i = 0; i < deg[expand_node]; i++)
             if (aux_deg[T[expand_node][i]] > 1)
                break;
         if (i == deg[expand_node])
            break;
         parent[expand_node] = T[expand_node][i];
         if ((--aux_deg[T[expand_node][i]]) == 1)
            Q[++qr] = T[expand_node][i];
     }
     parent[Q[qr]] = -1;
}

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

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

int resolve(int len)
{
    int i, cabans = 0;
    
    memset(U, 0, sizeof(U));
    memset(request, 0x3f, sizeof(request));
    memset(extra, 0xff, sizeof(extra));
    
    for (i = 0; i < N; i++)
        if (deg[Q[i]] == 1)
           request[Q[i]] = len;
    for (i = 0; (i + 1) < N; i++)
    {
        int en = Q[i], ex = extra[en], rq = request[en];
        
        if (!rq)
           U[en] = 1, ex = len + 1, rq = (len << 1) + 1, cabans++;
        else
        if (len - rq <= ex)
           rq = len + 1;
           
        request[parent[en]] = min(request[parent[en]], rq - 1);
        extra[parent[en]] = max(extra[parent[en]], ex - 1);
    }
    if (request[Q[N - 1]] < len)
       U[Q[N - 1]] = 1, cabans++;
    
    return cabans;
}

int main(void)
{
    int i, j, need_cabans, step, len;
    
    freopen(FIN, "r", stdin);
    freopen(FOUT, "w", stdout);
    
    scanf("%d%d", &N, &M);
    #ifdef TESTING
        X = (int *) malloc(sizeof(int) * MAX_N);
        Y = (int *) malloc(sizeof(int) * MAX_N);

        for (i = 1; i < N; i++)
        {
            scanf("%d%d", &X[i], &Y[i]);
            deg[X[i]]++, deg[Y[i]]++;
        }
        
        for (i = 1; i <= N; i++)
            T[i] = (int *) malloc(sizeof(int) * deg[i]);
            
        memset(deg, 0, sizeof(deg));
        
        for (i = 1; i < N; i++)
        {
            T[X[i]][deg[X[i]]++] = Y[i];
            T[Y[i]][deg[Y[i]]++] = X[i];
        }
    #else
        for (i = 1; i <= N; i++)
        {
            scanf("%d", &deg[i]);
            T[i] = (int *) malloc(sizeof(int) * deg[i]);
            for (j = 0; j < deg[i]; j++)
                scanf("%d", &T[i][j]);
        }
    #endif
    
    #ifdef DEBUG
        for (i = 1; i <= N; i++)
        {
            printf("%d ", deg[i]);
            for (j = 0; j < deg[i]; j++)
                printf("%d ", T[i][j]);
            printf("\n");
        }
    #endif
    
    enumerate(Q);
    
    #ifdef DEBUG
        printf("\n\n");
        for (i = 0; i < N; i++)
            printf("%d ", Q[i]);
        printf("\n");
    #endif    

    for (step = 1; step < N; step <<= 1) ;
    for (len = N; step; step >>= 1)
        if (len - step >= 0 && resolve(len - step) <= M)
           len -= step;
           
    need_cabans = resolve(len);
    
    #ifdef TESTING
        printf("%d\n", len);
    #else
        printf("%d %d\n", len, need_cabans);
    #endif
    
    for (i = 1; i <= N; i++)
        if (U[i])
           printf("%d ", i);

    return 0;
}