Cod sursa(job #169857)

Utilizator marius.pungaruMarius Pungaru marius.pungaru Data 2 aprilie 2008 03:12:04
Problema Salvare Scor 0
Compilator c Status done
Runda Arhiva de probleme Marime 2.99 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TESTING

#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], *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 (deg[T[expand_node][i]] > 1)
                break;
         parent[expand_node] = T[expand_node][i];
         if ((deg[T[expand_node][i]]--) == 2)
            Q[++qr] = T[expand_node][i];
     }
     parent[Q[qr]] = -1;
}

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

int resolve(int len)
{
    int i, cabans = 0;
    
    memset(request, 0x3f, sizeof(request));
    memset(U, 0, sizeof(U));
    
    for (i = 0; i < N; i++)
        if (deg[Q[i]] == 1)
           request[Q[i]] = len;
    for (i = 0; i < N; i++)
    {
        if (!request[Q[i]])
           U[Q[i]] = 1, request[Q[i]] = (len << 1) + 1, cabans++;
        if (parent[Q[i]] > 0)
           request[parent[Q[i]]] = min(request[parent[Q[i]]], request[Q[i]] - 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
    
    enumerate(Q);
    
    for (step = 1; step < N; step <<= 1) ;
    for (len = N; step; step >>= 1)
        if (len - step >= 0 && resolve(step - len) <= 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;
}