Cod sursa(job #55411)

Utilizator filipbFilip Cristian Buruiana filipb Data 27 aprilie 2007 13:25:11
Problema Salvare Scor Ascuns
Compilator cpp Status done
Runda Marime 2.77 kb
#include <stdio.h>
#include <string.h>
#include <vector>
#define maxim(a, b) ((a > b) ? a : b)
#define NMax 1020

using namespace std;

int N, K, H[NMax], sel[NMax], P[NMax], bst = 0;
vector<int> G[NMax];

void dfs(int nod)
{
     vector<int>::iterator it;

     H[nod] = 0;
     for (it = G[nod].begin(); it != G[nod].end(); it++)
         if (H[*it] == -1 && !P[*it])
         { dfs(*it); H[nod] = maxim(H[nod], H[*it]+1); }
}

int DMIN, q[NMax], O[NMax], uz[NMax], viz[NMax];

void dfs_new(int nod)
{
    int ok;
    vector<int>::iterator it;

    viz[nod] = 1;
    for (it = G[nod].begin(), ok = 1; it != G[nod].end(); it++)
    {
        if (!viz[*it] && !P[*it])
        {        
           dfs_new(*it);
           if (!O[*it])
              ok = 0;
        }
    }

    if (ok && uz[nod] <= DMIN)
       O[nod] = 1;
    else
       O[nod] = 0;
           
}

int BF(int sursa, int D)
{
    int i, ql, qr;
    vector<int>::iterator it;

    memset(uz, -1, sizeof(uz));
    for (q[ql=qr=0]=sursa, uz[sursa] = 0; qr <= ql; qr++)
        for (it = G[q[qr]].begin(); it != G[q[qr]].end(); it++)
            if (uz[*it] == -1)
            {
                q[++ql] = *it;
                uz[*it] = uz[q[qr]] + 1;
            }


    memset(viz, 0, sizeof(viz));
    memset(O, 0, sizeof(O));

    DMIN = D;
    dfs_new(1);

    for (i = 1; i <= N; i++)
        P[i] |= O[i];
}

int check(int D)
{
    int i, j, last_sel, puse = -1;
    
    memset(sel, 0, sizeof(sel));
    memset(P, 0, sizeof(P));
    
    for (i = 1; i <= K; i++)
    {
        memset(H, -1, sizeof(H));

        H[1] = 0; dfs(1);
        for (j = 1, last_sel = -1; j <= N; j++)
            if (H[j] == D)
            { last_sel = j; sel[j] = 1; P[j] = 1; break; }

        if (last_sel == -1)
           last_sel = 1;

        BF(last_sel, D);
            
        if (P[1])
        { puse = i; break; }
        
    }

    if (puse > 0 && puse <= K)
    {
        for (i = 1; puse < K; i++)
            if (!sel[i])
               sel[i] = 1, puse++;

        return 1;
    }
    else
        return 0;
        
}

int main(void)
{
    int i, u, v, ok, l, r, m;
    
    freopen("salvare.in", "r", stdin);
    freopen("salvare.out", "w", stdout);

    scanf("%d %d", &N, &K);
    for (i = 1; i < N; i++)
    {
        scanf("%d %d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }

    l = 1; r = 2*N;
    while (l <= r)
    {
        m = (l + r) / 2;
        ok = check(m);

        if (ok) bst = m, r = m-1;
        else l = m+1;
    }

    printf("%d\n", bst);
    check(bst);
    for (i = 1; i <= N; i++)
        if (sel[i])
           printf("%d ", i);
    printf("\n");

    return 0;
}