Cod sursa(job #55450)

Utilizator victorsbVictor Rusu victorsb Data 27 aprilie 2007 14:25:20
Problema Salvare Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.06 kb
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;

#define Nmax 1024
#define pb push_back
#define sz size()

int n, k, sol, m;
vector<int> lv[Nmax];
int t[Nmax], v[Nmax], c[Nmax], ad[Nmax], sir[Nmax], list[Nmax], s[Nmax], mrk[Nmax];

void citire()
{
    int i, a, b;
    
    scanf("%d\n", &n);
    scanf("%d\n", &k);
    for (i = 1; i < n; ++i)
    {
        scanf("%d %d\n", &a, &b);
        lv[a].pb(b);
        lv[b].pb(a);
    }
}

void bf()
{
    int st = 0, dr, nod, i, lim;
    
    c[dr = 1] = 1;
    v[1] = ad[1] = 1;
    
    while (st < dr)
    {
        nod = c[++st];
        lim = lv[nod].sz;
        for (i = 0; i < lim; ++i)
            if (!v[lv[nod][i]])
            {
                v[lv[nod][i]] = 1;
                ad[lv[nod][i]] = ad[nod] + 1;
                t[lv[nod][i]] = nod;
                c[++dr] = lv[nod][i];
            }
    }
}

int cmp(const int a, const int b)
{
    return ad[a] > ad[b];
}

void mark(int s, int d)
{
    int st = 0, dr, i, lim, nod;
    c[dr = 1] = s;
    memset(mrk, 0, sizeof(mrk));
    mrk[s] = 1;
    
    while (st < dr)
    {
        nod = c[++st];
        lim = lv[nod].sz;
        if (mrk[nod] > d)
            break;
        for (i = 0; i < lim; ++i)
            if (!mrk[lv[nod][i]])
            {
                mrk[lv[nod][i]] = mrk[nod] + 1;
                c[++dr] = lv[nod][i];
            }
    }
    
    for (i = 1; i <= n; ++i)
        if (mrk[i]) v[i] = 1;
}

int merge(int d)
{
    int i, j, ct = 0, nod, ok;
    
    memset(v, 0, sizeof(v));
    
    for (i = 1; i <= n; ++i)
    {
        if (!v[sir[i]])
        {
            nod = sir[i];
            for (j = 1; j <= d; ++j)
                if (t[nod])
                   nod = t[nod];
                else break;
            list[++ct] = nod;
            mark(nod, d);
        }
        
        if (ct == k) break;
    }
    
    ok = 1;
    for (i = 1; i <= n; ++i)
        if (!v[i])
        {
            ok = 0;
            break;
        }
    
    if (ok)
    {
        m = d;
        sol = ct;
        for (i = 1; i <= ct; ++i)
            s[i] = list[i];
    }
    return ok;
}

void solve()
{
    int st, dr, mij, i;
    
    bf();
    
    for (i = 1; i <= n; ++i) sir[i] = i;
    
    sort(sir+1, sir+n+1, cmp);
    
    st = 0;
    dr = n;
    
    while (st <= dr)
    {
        mij = (st + dr) / 2;
        
        if (merge(mij))
            dr = mij - 1;
        else
            st = mij + 1;
    }
    
    memset(v, 0, sizeof(v));
    for (i = 1; i <= sol; ++i)
        v[s[i]] = 1;
    for (i = 1; i <= n && sol < k; ++i)
        if (!v[i])
        {
            v[i] = 1;
            ++sol;
        }
    
    printf("%d\n", m);
    for (i = 1; i <= n; ++i)
        if (v[i])
           printf("%d ", i);
    printf("\n");
}

int main()
{
    freopen("salvare.in", "r", stdin);
    freopen("salvare.out", "w", stdout);
    citire();
    solve();
    return 0;
}